From 7d030a145ee5e7f9aaf653fbb1d64a1518c13fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 01:21:31 +0100 Subject: Remove attribute that is never used. --- src/input/input_http.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/input/input_http.c b/src/input/input_http.c index f2e91c226..ef2606413 100644 --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -77,7 +77,6 @@ typedef struct { off_t contentlength; char buf[BUFSIZE]; - char proxybuf[BUFSIZE]; char preview[MAX_PREVIEW_SIZE]; off_t preview_size; -- cgit v1.2.3 From d4149504575cf86fe492bf9ba1390d9ca33ab484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 01:28:16 +0100 Subject: Use strcat, delay calculation of resp_len. --- src/input/libreal/real.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c index 925b0fdf8..3a01e546a 100644 --- a/src/input/libreal/real.c +++ b/src/input/libreal/real.c @@ -353,10 +353,10 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe calc_response_string (response, buf); /* add tail */ - resp_len = strlen (response); - strcpy (&response[resp_len], "01d0a8e3"); + strcat(response, "01d0a8a3"); /* calculate checksum */ + resp_len = strlen (response); for (i=0; i Date: Wed, 19 Dec 2007 01:28:54 +0100 Subject: Use a zeroed allocation for buf rather than using memset. --- src/input/libreal/real.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c index 3a01e546a..29376868c 100644 --- a/src/input/libreal/real.c +++ b/src/input/libreal/real.c @@ -316,14 +316,13 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe int ch_len, resp_len; int i; char *ptr; - char buf[128]; + char buf[128] = { 0, }; /* initialize return values */ memset(response, 0, 64); memset(chksum, 0, 34); /* initialize buffer */ - memset(buf, 0, 128); ptr=buf; _X_BE_32C(ptr, 0xa1e9149d); ptr+=4; -- cgit v1.2.3 From 530ba72be38719c9857afecea9e77fe1c5df3137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 01:40:26 +0100 Subject: Remove xine_strdupa declaration, and macro. --- src/xine-utils/xineutils.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src') diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h index 3296b2ba9..4ff87e87c 100644 --- a/src/xine-utils/xineutils.h +++ b/src/xine-utils/xineutils.h @@ -657,21 +657,6 @@ char *xine_chomp (char *str) XINE_PROTECTED; */ void xine_usec_sleep(unsigned usec) XINE_PROTECTED; - - /* - * Some string functions - */ - - -void xine_strdupa(char *dest, char *src) XINE_PROTECTED; -#define xine_strdupa(d, s) do { \ - (d) = NULL; \ - if((s) != NULL) { \ - (d) = (char *) alloca(strlen((s)) + 1); \ - strcpy((d), (s)); \ - } \ - } while(0) - /* compatibility macros */ #define xine_strpbrk(S, ACCEPT) strpbrk((S), (ACCEPT)) #define xine_strsep(STRINGP, DELIM) strsep((STRINGP), (DELIM)) -- cgit v1.2.3 From f80c8d4d48e7a5ef6ac6c9f2a4dfdb39f40aaff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 02:10:56 +0100 Subject: Consolidate all public include files into include/xine directory. --HG-- rename : src/xine-engine/alphablend.h => include/xine/alphablend.h rename : src/xine-utils/array.h => include/xine/array.h rename : src/xine-utils/attributes.h => include/xine/attributes.h rename : src/xine-engine/audio_decoder.h => include/xine/audio_decoder.h rename : src/xine-engine/audio_out.h => include/xine/audio_out.h rename : src/xine-engine/broadcaster.h => include/xine/broadcaster.h rename : src/xine-engine/buffer.h => include/xine/buffer.h rename : src/xine-utils/compat.h => include/xine/compat.h rename : src/xine-engine/configfile.h => include/xine/configfile.h rename : src/demuxers/demux.h => include/xine/demux.h rename : src/xine-engine/info_helper.h => include/xine/info_helper.h rename : src/input/input_plugin.h => include/xine/input_plugin.h rename : src/xine-engine/io_helper.h => include/xine/io_helper.h rename : src/xine-utils/list.h => include/xine/list.h rename : src/xine-engine/metronom.h => include/xine/metronom.h rename : src/xine-engine/osd.h => include/xine/osd.h rename : src/xine-engine/plugin_catalog.h => include/xine/plugin_catalog.h rename : src/xine-utils/pool.h => include/xine/pool.h rename : src/xine-engine/post.h => include/xine/post.h rename : src/xine-engine/refcounter.h => include/xine/refcounter.h rename : src/xine-engine/resample.h => include/xine/resample.h rename : src/xine-utils/ring_buffer.h => include/xine/ring_buffer.h rename : src/xine-engine/scratch.h => include/xine/scratch.h rename : src/xine-utils/sorted_array.h => include/xine/sorted_array.h rename : src/xine-engine/spu.h => include/xine/spu.h rename : src/xine-engine/spu_decoder.h => include/xine/spu_decoder.h rename : src/xine-engine/video_decoder.h => include/xine/video_decoder.h rename : src/xine-engine/video_out.h => include/xine/video_out.h rename : src/xine-engine/video_overlay.h => include/xine/video_overlay.h rename : src/xine-engine/vo_scale.h => include/xine/vo_scale.h rename : src/xine-utils/xine_buffer.h => include/xine/xine_buffer.h rename : src/xine-engine/xine_internal.h => include/xine/xine_internal.h rename : src/xine-engine/xine_plugin.h => include/xine/xine_plugin.h rename : src/xine-engine/xineintl.h => include/xine/xineintl.h rename : src/xine-utils/xineutils.h => include/xine/xineutils.h rename : src/xine-utils/xmllexer.h => include/xine/xmllexer.h rename : src/xine-utils/xmlparser.h => include/xine/xmlparser.h --- src/demuxers/Makefile.am | 2 - src/demuxers/demux.h | 220 --------- src/input/input_plugin.h | 420 ----------------- src/vdr/Makefile.am | 2 - src/xine-engine/Makefile.am | 6 - src/xine-engine/alphablend.h | 113 ----- src/xine-engine/audio_decoder.h | 105 ----- src/xine-engine/audio_out.h | 352 -------------- src/xine-engine/broadcaster.h | 46 -- src/xine-engine/buffer.h | 718 ----------------------------- src/xine-engine/configfile.h | 218 --------- src/xine-engine/info_helper.h | 180 -------- src/xine-engine/io_helper.h | 141 ------ src/xine-engine/metronom.h | 364 --------------- src/xine-engine/osd.h | 365 --------------- src/xine-engine/plugin_catalog.h | 95 ---- src/xine-engine/post.h | 405 ---------------- src/xine-engine/refcounter.h | 46 -- src/xine-engine/resample.h | 62 --- src/xine-engine/scratch.h | 56 --- src/xine-engine/spu.h | 44 -- src/xine-engine/spu_decoder.h | 151 ------ src/xine-engine/video_decoder.h | 111 ----- src/xine-engine/video_out.h | 466 ------------------- src/xine-engine/video_overlay.h | 68 --- src/xine-engine/vo_scale.h | 203 -------- src/xine-engine/xine_internal.h | 546 ---------------------- src/xine-engine/xine_plugin.h | 105 ----- src/xine-engine/xineintl.h | 54 --- src/xine-utils/Makefile.am | 13 - src/xine-utils/array.h | 57 --- src/xine-utils/attributes.h | 86 ---- src/xine-utils/compat.h | 55 --- src/xine-utils/list.h | 104 ----- src/xine-utils/pool.h | 48 -- src/xine-utils/ring_buffer.h | 55 --- src/xine-utils/sorted_array.h | 94 ---- src/xine-utils/xine_buffer.h | 136 ------ src/xine-utils/xineutils.h | 972 --------------------------------------- src/xine-utils/xmllexer.h | 59 --- src/xine-utils/xmlparser.h | 99 ---- 41 files changed, 7442 deletions(-) delete mode 100644 src/demuxers/demux.h delete mode 100644 src/input/input_plugin.h delete mode 100644 src/xine-engine/alphablend.h delete mode 100644 src/xine-engine/audio_decoder.h delete mode 100644 src/xine-engine/audio_out.h delete mode 100644 src/xine-engine/broadcaster.h delete mode 100644 src/xine-engine/buffer.h delete mode 100644 src/xine-engine/configfile.h delete mode 100644 src/xine-engine/info_helper.h delete mode 100644 src/xine-engine/io_helper.h delete mode 100644 src/xine-engine/metronom.h delete mode 100644 src/xine-engine/osd.h delete mode 100644 src/xine-engine/plugin_catalog.h delete mode 100644 src/xine-engine/post.h delete mode 100644 src/xine-engine/refcounter.h delete mode 100644 src/xine-engine/resample.h delete mode 100644 src/xine-engine/scratch.h delete mode 100644 src/xine-engine/spu.h delete mode 100644 src/xine-engine/spu_decoder.h delete mode 100644 src/xine-engine/video_decoder.h delete mode 100644 src/xine-engine/video_out.h delete mode 100644 src/xine-engine/video_overlay.h delete mode 100644 src/xine-engine/vo_scale.h delete mode 100644 src/xine-engine/xine_internal.h delete mode 100644 src/xine-engine/xine_plugin.h delete mode 100644 src/xine-engine/xineintl.h delete mode 100644 src/xine-utils/array.h delete mode 100644 src/xine-utils/attributes.h delete mode 100644 src/xine-utils/compat.h delete mode 100644 src/xine-utils/list.h delete mode 100644 src/xine-utils/pool.h delete mode 100644 src/xine-utils/ring_buffer.h delete mode 100644 src/xine-utils/sorted_array.h delete mode 100644 src/xine-utils/xine_buffer.h delete mode 100644 src/xine-utils/xineutils.h delete mode 100644 src/xine-utils/xmllexer.h delete mode 100644 src/xine-utils/xmlparser.h (limited to 'src') diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am index ba3041d5d..276505521 100644 --- a/src/demuxers/Makefile.am +++ b/src/demuxers/Makefile.am @@ -8,8 +8,6 @@ AM_LDFLAGS = $(xineplug_ldflags) # --------- # All of xine demuxer plugins should be named like the scheme "xineplug_dmx_" -xineinclude_HEADERS = demux.h - noinst_HEADERS = asfheader.h qtpalette.h group_games.h group_audio.h id3.h ebml.h matroska.h iff.h flacutils.h if ENABLE_ASF diff --git a/src/demuxers/demux.h b/src/demuxers/demux.h deleted file mode 100644 index ee5ca42f0..000000000 --- a/src/demuxers/demux.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef HAVE_DEMUX_H -#define HAVE_DEMUX_H - -#ifdef XINE_COMPILE -# include "input/input_plugin.h" -# include "buffer.h" -# include "xine_internal.h" -#else -# include -# include -# include -#endif - -#define DEMUXER_PLUGIN_IFACE_VERSION 27 - -#define DEMUX_OK 0 -#define DEMUX_FINISHED 1 - -#define DEMUX_CANNOT_HANDLE 0 -#define DEMUX_CAN_HANDLE 1 - -#define METHOD_BY_CONTENT 1 -#define METHOD_BY_MRL 2 -#define METHOD_EXPLICIT 3 - -typedef struct demux_class_s demux_class_t ; -typedef struct demux_plugin_s demux_plugin_t; - -struct demux_class_s { - - /* - * open a new instance of this plugin class - */ - demux_plugin_t* (*open_plugin) (demux_class_t *this, xine_stream_t *stream, input_plugin_t *input); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /** - * @brief MIME types supported for this plugin - */ - - const char* mimetypes; - - /** - * @brief space separated list of file extensions this demuxer is - * likely to handle - * - * (will be used to filter media files in file selection dialogs) - */ - const char* extensions; - - /* - * close down, free all resources - */ - void (*dispose) (demux_class_t *this); -}; - -#define default_demux_class_dispose (void (*) (demux_class_t *this))free - -/* - * any demux plugin must implement these functions - */ - -struct demux_plugin_s { - - /* - * send headers, followed by BUF_CONTROL_HEADERS_DONE down the - * fifos, then return. do not start demux thread (yet) - */ - - void (*send_headers) (demux_plugin_t *this); - - /* - * ask demux to seek - * - * for seekable streams, a start position can be specified - * - * start_pos : position in input source (0..65535) - * this is defined as most convenient to demuxer, can be - * either time or offset based. - * start_time : position measured in miliseconds from stream start - * playing : true if this is a new seek within an already playing stream - * false if playback of this stream has not started yet - * - * if both parameters are !=0 start_pos will be used - * for non-seekable streams both values will be ignored - * - * returns the demux status (like get_status, but immediately after - * starting the demuxer) - */ - - int (*seek) (demux_plugin_t *this, - off_t start_pos, int start_time, int playing ); - - /* - * send a chunk of data down to decoder fifos - * - * the meaning of "chunk" is specific to every demux, usually - * it involves parsing one unit of data from stream. - * - * this function will be called from demux loop and should return - * the demux current status - */ - - int (*send_chunk) (demux_plugin_t *this); - - /* - * free resources - */ - - void (*dispose) (demux_plugin_t *this) ; - - /* - * returns DEMUX_OK or DEMUX_FINISHED - */ - - int (*get_status) (demux_plugin_t *this) ; - - /* - * gets stream length in miliseconds (might be estimated) - * may return 0 for non-seekable streams - */ - - int (*get_stream_length) (demux_plugin_t *this); - - /* - * return capabilities of demuxed stream - */ - - uint32_t (*get_capabilities) (demux_plugin_t *this); - - /* - * request optional data from input plugin. - */ - int (*get_optional_data) (demux_plugin_t *this, void *data, int data_type); - - /* - * "backwards" link to plugin class - */ - - demux_class_t *demux_class; - - void *node; /* used by plugin loader */ - -} ; - -#define default_demux_plugin_dispose (void (*) (demux_plugin_t *this))free - -/* - * possible capabilites a demux plugin can have: - */ -#define DEMUX_CAP_NOCAP 0x00000000 - -/* - * DEMUX_CAP_AUDIOLANG: - * DEMUX_CAP_SPULANG: - * demux plugin knows something about audio/spu languages, - * e.g. knows that audio stream #0 is english, - * audio stream #1 is german, ... Same bits as INPUT - * capabilities . - */ - -#define DEMUX_CAP_AUDIOLANG 0x00000008 -#define DEMUX_CAP_SPULANG 0x00000010 - -/* - * DEMUX_CAP_CHAPTERS: - * The media streams provided by this plugin have an internal - * structure dividing it into segments usable for navigation. - * For those plugins, the behaviour of the skip button in UIs - * should be changed from "next MRL" to "next chapter" by - * sending XINE_EVENT_INPUT_NEXT. - * Same bits as INPUT capabilities. - */ - -#define DEMUX_CAP_CHAPTERS 0x00000080 - - -#define DEMUX_OPTIONAL_UNSUPPORTED 0 -#define DEMUX_OPTIONAL_SUCCESS 1 - -#define DEMUX_OPTIONAL_DATA_AUDIOLANG 2 -#define DEMUX_OPTIONAL_DATA_SPULANG 3 - -#endif diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h deleted file mode 100644 index 2917721c9..000000000 --- a/src/input/input_plugin.h +++ /dev/null @@ -1,420 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef HAVE_INPUT_PLUGIN_H -#define HAVE_INPUT_PLUGIN_H - -#include - -#ifdef XINE_COMPILE -# include -# include "xineutils.h" -# include "buffer.h" -# include "configfile.h" -#else -# include -# include -# include -# include -#endif - -#define INPUT_PLUGIN_IFACE_VERSION 18 - -typedef struct input_class_s input_class_t ; -typedef struct input_plugin_s input_plugin_t; - -struct input_class_s { - - /* - * create a new instance of this plugin class - * return NULL if the plugin does'nt handle the given mrl - */ - input_plugin_t* (*get_instance) (input_class_t *this, xine_stream_t *stream, const char *mrl); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * ls function, optional: may be NULL - * return value: NULL => filename is a file, **char=> filename is a dir - */ - xine_mrl_t ** (*get_dir) (input_class_t *this, const char *filename, int *nFiles); - - /* - * generate autoplay list, optional: may be NULL - * return value: list of MRLs - */ - char ** (*get_autoplay_list) (input_class_t *this, int *num_files); - - /* - * close down, free all resources - */ - void (*dispose) (input_class_t *this); - - /* - * eject/load the media (if possible), optional: may be NULL - * - * returns 0 for temporary failures - */ - int (*eject_media) (input_class_t *this); -}; - -#define default_input_class_dispose (void (*) (input_class_t *this))free - -struct input_plugin_s { - - /* - * open the stream - * return 0 if an error occured - */ - int (*open) (input_plugin_t *this); - - /* - * return capabilities of the current playable entity. See - * get_current_pos below for a description of a "playable entity" - * Capabilities a created by "OR"ing a mask of constants listed - * below which start "INPUT_CAP". - * - * depending on the values set, some of the functions below - * will or will not get called or should (not) be able to - * do certain tasks. - * - * for example if INPUT_CAP_SEEKABLE is set, - * the seek() function is expected to work fully at any time. - * however, if the flag is not set, the seek() function should - * make a best-effort attempt to seek, e.g. at least - * relative forward seeking should work. - */ - uint32_t (*get_capabilities) (input_plugin_t *this); - - /* - * read nlen bytes, return number of bytes read - * Should block until some bytes available for read; - * a return value of 0 indicates no data available - */ - off_t (*read) (input_plugin_t *this, void *buf, off_t nlen); - - - /* - * read one block, return newly allocated block (or NULL on failure) - * for blocked input sources len must be == blocksize - * the fifo parameter is only used to get access to the buffer_pool_alloc function - */ - buf_element_t *(*read_block)(input_plugin_t *this, fifo_buffer_t *fifo, off_t len); - - - /* - * seek position, return new position - * - * if seeking failed, -1 is returned - */ - off_t (*seek) (input_plugin_t *this, off_t offset, int origin); - - - /* - * seek to time position, return new position - * time_offset is given in miliseconds - * - * if seeking failed, -1 is returned - * - * note: only SEEK_SET (0) is currently supported as origin - * note: may be NULL is not supported - */ - off_t (*seek_time) (input_plugin_t *this, int time_offset, int origin); - - - /* - * get current position in stream. - * - */ - off_t (*get_current_pos) (input_plugin_t *this); - - - /* - * get current time position in stream in miliseconds. - * - * note: may be NULL is not supported - */ - int (*get_current_time) (input_plugin_t *this); - - - /* - * return number of bytes in the next playable entity or -1 if the - * input is unlimited, as would be the case in a network stream. - * - * A "playable entity" tends to be the entities listed in a playback - * list or the units on which playback control generally works on. - * It might be the number of bytes in a VCD "segment" or "track" (if - * the track has no "entry" subdivisions), or the number of bytes in - * a PS (Program Segment or "Chapter") of a DVD. If there are no - * subdivisions of the input medium and it is considered one - * indivisible entity, it would be the byte count of that entity; - * for example, the length in bytes of an MPEG file. - - * This length information is used, for example when in setting the - * absolute or relative play position or possibly calculating the - * bit rate. - */ - off_t (*get_length) (input_plugin_t *this); - - - /* - * return block size in bytes of next complete playable entity (if - * supported, 0 otherwise). See the description above under - * get_length for a description of a "complete playable entity". - * - * this block size is only used for mpeg streams stored on - * a block oriented storage media, e.g. DVDs and VCDs, to speed - * up the demuxing process. only set this (and the INPUT_CAP_BLOCK - * flag) if this is the case for your input plugin. - * - * make this function simply return 0 if unsure. - */ - - uint32_t (*get_blocksize) (input_plugin_t *this); - - - /* - * return current MRL - */ - const char * (*get_mrl) (input_plugin_t *this); - - - /* - * request optional data from input plugin. - */ - int (*get_optional_data) (input_plugin_t *this, void *data, int data_type); - - - /* - * close stream, free instance resources - */ - void (*dispose) (input_plugin_t *this); - - /* - * "backward" link to input plugin class struct - */ - - input_class_t *input_class; - - void *node; /* used by plugin loader */ - -}; - -/* - * possible capabilites an input plugin can have: - */ -#define INPUT_CAP_NOCAP 0x00000000 - -/* - * INPUT_CAP_SEEKABLE: - * seek () works reliably. - * even for plugins that do not have this flag set - * it is a good idea to implement the seek() function - * in a "best effort" style anyway, so at least - * throw away data for network streams when seeking forward - */ - -#define INPUT_CAP_SEEKABLE 0x00000001 - -/* - * INPUT_CAP_BLOCK: - * means more or less that a block device sits behind - * this input plugin. get_blocksize must be implemented. - * will be used for fast and efficient demuxing of - * mpeg streams (demux_mpeg_block). - */ - -#define INPUT_CAP_BLOCK 0x00000002 - -/* - * INPUT_CAP_AUDIOLANG: - * INPUT_CAP_SPULANG: - * input plugin knows something about audio/spu languages, - * e.g. knows that audio stream #0 is english, - * audio stream #1 is german, ... - * *((int *)data) will provide the requested channel number - * and awaits the language back in (char *)data - */ - -#define INPUT_CAP_AUDIOLANG 0x00000008 -#define INPUT_CAP_SPULANG 0x00000010 - -/* - * INPUT_CAP_PREVIEW: - * get_optional_data can handle INPUT_OPTIONAL_DATA_PREVIEW - * so a non-seekable stream plugin can povide the first - * few bytes for demuxers to look at them and decide wheter - * they can handle the stream or not. the preview data must - * be buffered and delivered again through subsequent - * read() calls. - * caller must provide a buffer allocated with at least - * MAX_PREVIEW_SIZE bytes. - */ - -#define INPUT_CAP_PREVIEW 0x00000040 - -/* - * INPUT_CAP_CHAPTERS: - * The media streams provided by this plugin have an internal - * structure dividing it into segments usable for navigation. - * For those plugins, the behaviour of the skip button in UIs - * should be changed from "next MRL" to "next chapter" by - * sending XINE_EVENT_INPUT_NEXT. - */ - -#define INPUT_CAP_CHAPTERS 0x00000080 - -/* - * INPUT_CAP_RIP_FORBIDDEN: - * means that rip/disk saving must not be used. - * (probably at author's request) - */ - -#define INPUT_CAP_RIP_FORBIDDEN 0x00000100 - - -#define INPUT_IS_SEEKABLE(input) (((input)->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) - -#define INPUT_OPTIONAL_UNSUPPORTED 0 -#define INPUT_OPTIONAL_SUCCESS 1 - -#define INPUT_OPTIONAL_DATA_AUDIOLANG 2 -#define INPUT_OPTIONAL_DATA_SPULANG 3 -#define INPUT_OPTIONAL_DATA_PREVIEW 7 - -#define MAX_MRL_ENTRIES 255 -#define MAX_PREVIEW_SIZE 4096 - -/* Types of mrls returned by get_dir() */ -#define mrl_unknown (0 << 0) -#define mrl_dvd (1 << 0) -#define mrl_vcd (1 << 1) -#define mrl_net (1 << 2) -#define mrl_rtp (1 << 3) -#define mrl_stdin (1 << 4) -#define mrl_cda (1 << 5) -#define mrl_file (1 << 6) -#define mrl_file_fifo (1 << 7) -#define mrl_file_chardev (1 << 8) -#define mrl_file_directory (1 << 9) -#define mrl_file_blockdev (1 << 10) -#define mrl_file_normal (1 << 11) -#define mrl_file_symlink (1 << 12) -#define mrl_file_sock (1 << 13) -#define mrl_file_exec (1 << 14) -#define mrl_file_backup (1 << 15) -#define mrl_file_hidden (1 << 16) - -/* - * Freeing/zeroing all of entries of given mrl. - */ -#define MRL_ZERO(m) { \ - if((m)) { \ - if((m)->origin) \ - free((m)->origin); \ - if((m)->mrl) \ - free((m)->mrl); \ - if((m)->link) \ - free((m)->link); \ - (m)->origin = NULL; \ - (m)->mrl = NULL; \ - (m)->link = NULL; \ - (m)->type = 0; \ - (m)->size = (off_t) 0; \ - } \ -} - -/* - * Duplicate two mrls entries (s = source, d = destination). - */ -#define MRL_DUPLICATE(s, d) { \ - _x_assert((s) != NULL); \ - _x_assert((d) != NULL); \ - \ - if((s)->origin) { \ - if((d)->origin) { \ - (d)->origin = (char *) realloc((d)->origin, strlen((s)->origin) + 1); \ - sprintf((d)->origin, "%s", (s)->origin); \ - } \ - else \ - (d)->origin = strdup((s)->origin); \ - } \ - else \ - (d)->origin = NULL; \ - \ - if((s)->mrl) { \ - if((d)->mrl) { \ - (d)->mrl = (char *) realloc((d)->mrl, strlen((s)->mrl) + 1); \ - sprintf((d)->mrl, "%s", (s)->mrl); \ - } \ - else \ - (d)->mrl = strdup((s)->mrl); \ - } \ - else \ - (d)->mrl = NULL; \ - \ - if((s)->link) { \ - if((d)->link) { \ - (d)->link = (char *) realloc((d)->link, strlen((s)->link) + 1); \ - sprintf((d)->link, "%s", (s)->link); \ - } \ - else \ - (d)->link = strdup((s)->link); \ - } \ - else \ - (d)->link = NULL; \ - \ - (d)->type = (s)->type; \ - (d)->size = (s)->size; \ -} - -/* - * Duplicate two arrays of mrls (s = source, d = destination). - */ -#define MRLS_DUPLICATE(s, d) { \ - int i = 0; \ - \ - _x_assert((s) != NULL); \ - _x_assert((d) != NULL); \ - \ - while((s) != NULL) { \ - d[i] = (xine_mrl_t *) malloc(sizeof(xine_mrl_t)); \ - MRL_DUPLICATE(s[i], d[i]); \ - i++; \ - } \ -} - - -#endif diff --git a/src/vdr/Makefile.am b/src/vdr/Makefile.am index fcdf6cae4..e4912176a 100644 --- a/src/vdr/Makefile.am +++ b/src/vdr/Makefile.am @@ -3,8 +3,6 @@ include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) -xineinclude_HEADERS = input_vdr.h - if ENABLE_DVB xineplug_LTLIBRARIES = xineplug_inp_vdr.la xinepost_LTLIBRARIES = xineplug_post_vdr.la diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index b90bd0ee9..c509b62af 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -16,12 +16,6 @@ endif noinst_HEADERS = bswap.h ffmpeg_bswap.h -xineinclude_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \ - audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \ - video_overlay.h osd.h spu.h scratch.h xine_plugin.h xineintl.h \ - plugin_catalog.h audio_decoder.h video_decoder.h post.h \ - io_helper.h broadcaster.h info_helper.h refcounter.h alphablend.h - lib_LTLIBRARIES = libxine.la libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \ diff --git a/src/xine-engine/alphablend.h b/src/xine-engine/alphablend.h deleted file mode 100644 index f8c9ad540..000000000 --- a/src/xine-engine/alphablend.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Copyright (C) 2000 Thomas Mirlacher - * - * This program 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. - * - * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. - * - * The author may be reached as - * - *------------------------------------------------------------ - * - */ - -#ifndef __ALPHABLEND_H__ -#define __ALPHABLEND_H__ - -#include "video_out.h" - -typedef struct { - void *buffer; - int buffer_size; - - int disable_exact_blending; - - int offset_x, offset_y; -} alphablend_t; - -void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) XINE_PROTECTED; -void _x_alphablend_free(alphablend_t *extra_data) XINE_PROTECTED; - -typedef struct { /* CLUT == Color LookUp Table */ - uint8_t cb; - uint8_t cr; - uint8_t y; - uint8_t foo; -} XINE_PACKED clut_t; - - -#define XX44_PALETTE_SIZE 32 - -typedef struct { - unsigned size; - unsigned max_used; - uint32_t cluts[XX44_PALETTE_SIZE]; - /* cache palette entries for both colors and hili_colors */ - int lookup_cache[OVL_PALETTE_SIZE*2]; -} xx44_palette_t; - - -void _x_blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, - int img_width, int img_height, - int dst_width, int dst_height, - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, - int img_width, int img_height, - int dst_width, int dst_height, - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, - int img_width, int img_height, - int dst_width, int dst_height, - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitches[3], - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitch, - alphablend_t *extra_data) XINE_PROTECTED; - -/* - * This function isn't too smart about blending. We want to avoid creating new - * colors in the palette as a result from two non-zero colors needed to be - * blended. Instead we choose the color with the highest alpha value to be - * visible. Some parts of the code taken from the "VeXP" project. - */ - -void _x_blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, - int dst_width, int dst_height, int dst_pitch, - alphablend_t *extra_data, - xx44_palette_t *palette,int ia44) XINE_PROTECTED; - -/* - * Functions to handle the xine-specific palette. - */ - -void _x_clear_xx44_palette(xx44_palette_t *p) XINE_PROTECTED; -void _x_init_xx44_palette(xx44_palette_t *p, unsigned num_entries) XINE_PROTECTED; -void _x_dispose_xx44_palette(xx44_palette_t *p) XINE_PROTECTED; - -/* - * Convert the xine-specific palette to something useful. - */ - -void _x_xx44_to_xvmc_palette(const xx44_palette_t *p,unsigned char *xvmc_palette, - unsigned first_xx44_entry, unsigned num_xx44_entries, - unsigned num_xvmc_components, char *xvmc_components) XINE_PROTECTED; - - -#endif diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h deleted file mode 100644 index 307692b81..000000000 --- a/src/xine-engine/audio_decoder.h +++ /dev/null @@ -1,105 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine audio decoder plugin interface - */ - -#ifndef HAVE_AUDIO_DECODER_H -#define HAVE_AUDIO_DECODER_H - -#ifdef XINE_COMPILE -# include -# include "buffer.h" -#else -# include -# include -#endif - -#define AUDIO_DECODER_IFACE_VERSION 16 - -/* - * generic xine audio decoder plugin interface - */ - -typedef struct audio_decoder_class_s audio_decoder_class_t; -typedef struct audio_decoder_s audio_decoder_t; - -struct audio_decoder_class_s { - - /* - * open a new instance of this plugin class - */ - audio_decoder_t* (*open_plugin) (audio_decoder_class_t *this, xine_stream_t *stream); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * free all class-related resources - */ - - void (*dispose) (audio_decoder_class_t *this); -}; - -#define default_audio_decoder_class_dispose (void (*) (audio_decoder_class_t *this))free - -struct audio_decoder_s { - - /* - * decode data from buf and feed decoded samples to - * audio output - */ - void (*decode_data) (audio_decoder_t *this, buf_element_t *buf); - - /* - * reset decoder after engine flush (prepare for new - * audio data not related to recently decoded data) - */ - void (*reset) (audio_decoder_t *this); - - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - void (*discontinuity) (audio_decoder_t *this); - - /* - * close down, free all resources - */ - void (*dispose) (audio_decoder_t *this); - - void *node; /* used by plugin loader */ - -}; - -#endif diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h deleted file mode 100644 index bd1b910df..000000000 --- a/src/xine-engine/audio_out.h +++ /dev/null @@ -1,352 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ -#ifndef HAVE_AUDIO_OUT_H -#define HAVE_AUDIO_OUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(XINE_COMPILE) -#include -#include "metronom.h" -#include "configfile.h" -#include "xineutils.h" -#else -#include -#include -#include -#include -#endif - - -#define AUDIO_OUT_IFACE_VERSION 9 - -/* - * ao_driver_s contains the driver every audio output - * driver plugin has to implement. - */ - -typedef struct ao_driver_s ao_driver_t; - -struct ao_driver_s { - - /* - * - * find out what output modes + capatilities are supported by - * this plugin (constants for the bit vector to return see above) - * - * See AO_CAP_* bellow. - */ - uint32_t (*get_capabilities) (ao_driver_t *); - - /* - * open the driver and make it ready to receive audio data - * buffers may be flushed(!) - * - * return value: 0 : failure, >0 : output sample rate - */ - int (*open)(ao_driver_t *, uint32_t bits, uint32_t rate, int mode); - - /* return the number of audio channels - */ - int (*num_channels)(ao_driver_t *self_gen); - - /* return the number of bytes per frame. - * A frame is equivalent to one sample being output on every audio channel. - */ - int (*bytes_per_frame)(ao_driver_t *self_gen); - - /* return the delay is frames measured by - * looking at pending samples in the audio output device - */ - int (*delay)(ao_driver_t *self_gen); - - /* - * return gap tolerance (in pts) needed for this driver - */ - int (*get_gap_tolerance) (ao_driver_t *self_gen); - - /* - * write audio data to audio output device - * return value: - * >0 => audio samples were processed ok - * 0 => audio samples were not yet processed, - * call write_audio_data with the _same_ samples again - */ - int (*write)(ao_driver_t *, - int16_t* audio_data, uint32_t num_samples); - - /* - * this is called when the decoder no longer uses the audio - * output driver - the driver should get ready to get opened() again - */ - void (*close)(ao_driver_t *); - - /* - * shut down this audio output driver plugin and - * free all resources allocated - */ - void (*exit) (ao_driver_t *); - - /* - * Get, Set a property of audio driver. - * - * get_property() return 1 in success, 0 on failure. - * set_property() return value on success, ~value on failure. - * - * See AO_PROP_* below for available properties. - */ - int (*get_property) (ao_driver_t *, int property); - - int (*set_property) (ao_driver_t *, int property, int value); - - - /* - * misc control operations on the audio device. - * - * See AO_CTRL_* below. - */ - int (*control) (ao_driver_t *, int cmd, /* arg */ ...); - - void *node; -}; - -typedef struct ao_format_s ao_format_t; - -struct ao_format_s { - uint32_t bits; - uint32_t rate; - int mode; -}; - -typedef struct audio_fifo_s audio_fifo_t; - -typedef struct audio_buffer_s audio_buffer_t; - -struct audio_buffer_s { - - audio_buffer_t *next; - - int16_t *mem; - int mem_size; - int num_frames; - - int64_t vpts; - uint32_t frame_header_count; - uint32_t first_access_unit; - - /* extra info coming from input or demuxers */ - extra_info_t *extra_info; - - xine_stream_t *stream; /* stream that send that buffer */ - - ao_format_t format; /* let each buffer carry it's own format info */ -}; - -/* - * xine_audio_port_s contains the port every audio decoder talks to - * - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ - -struct xine_audio_port_s { - uint32_t (*get_capabilities) (xine_audio_port_t *); /* for constants see below */ - - /* * Get/Set audio property - * - * See AO_PROP_* bellow - */ - int (*get_property) (xine_audio_port_t *, int property); - int (*set_property) (xine_audio_port_t *, int property, int value); - - /* open audio driver for audio output - * return value: 0:failure, >0:output sample rate - */ - /* when you are not a full-blown stream, but still need to open the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - int (*open) (xine_audio_port_t *, xine_stream_t *stream, - uint32_t bits, uint32_t rate, int mode); - - /* - * get a piece of memory for audio data - */ - audio_buffer_t * (*get_buffer) (xine_audio_port_t *); - - /* - * append a buffer filled with audio data to the audio fifo - * for output - */ - /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */ - void (*put_buffer) (xine_audio_port_t *, audio_buffer_t *buf, xine_stream_t *stream); - - /* audio driver is no longer used by decoder => close */ - /* when you are not a full-blown stream, but still need to close the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - void (*close) (xine_audio_port_t *self, xine_stream_t *stream); - - /* called on xine exit */ - void (*exit) (xine_audio_port_t *); - - /* - * misc control operations on the audio device. - * - * See AO_CTRL_* below. - */ - int (*control) (xine_audio_port_t *, int cmd, /* arg */ ...); - - /* - * Flush audio_out fifo. - */ - void (*flush) (xine_audio_port_t *); - - /* - * Check if port is opened for this stream and get parameters. - * The stream can be anonymous. - */ - int (*status) (xine_audio_port_t *, xine_stream_t *stream, - uint32_t *bits, uint32_t *rate, int *mode); - -}; - -typedef struct audio_driver_class_s audio_driver_class_t; - -struct audio_driver_class_s { - - /* - * open a new instance of this plugin class - */ - ao_driver_t* (*open_plugin) (audio_driver_class_t *, const void *data); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * free all class-related resources - */ - - void (*dispose) (audio_driver_class_t *); -}; - -#define default_audio_driver_class_dispose (void (*) (audio_driver_class_t *this))free - -/** - * @brief Initialise the audio_out sync routines - * - * @internal - */ -xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only); - -/* - * audio output modes + capabilities - */ - -#define AO_CAP_NOCAP 0x00000000 /* driver has no capabilities */ -#define AO_CAP_MODE_A52 0x00000001 /* driver supports A/52 output */ -#define AO_CAP_MODE_AC5 0x00000002 /* driver supports AC5 output */ -/* 1 sample == 2 bytes (C) */ -#define AO_CAP_MODE_MONO 0x00000004 /* driver supports mono output */ -/* 1 sample == 4 bytes (L,R) */ -#define AO_CAP_MODE_STEREO 0x00000008 /* driver supports stereo output */ -/* 1 sample == 8 bytes (L,R,LR,RR) */ -#define AO_CAP_MODE_4CHANNEL 0x00000010 /* driver supports 4 channels */ -/* - * Sound cards generally support, 1,2,4,6 channels, but rarely 5. - * So xine will take 4.1, 5 and 6 channel a52 streams and - * down or upmix it correctly to fill the 6 output channels. - * Are there any requests for 2.1 out there? - */ -/* 1 sample == 12 bytes (L,R,LR,RR,Null,LFE) */ -#define AO_CAP_MODE_4_1CHANNEL 0x00000020 /* driver supports 4.1 channels */ -/* 1 sample == 12 bytes (L,R,LR,RR,C, Null) */ -#define AO_CAP_MODE_5CHANNEL 0x00000040 /* driver supports 5 channels */ -/* 1 sample == 12 bytes (L,R,LR,RR,C,LFE) */ -#define AO_CAP_MODE_5_1CHANNEL 0x00000080 /* driver supports 5.1 channels */ - -/* - * converts the audio output mode into the number of channels - */ -int _x_ao_mode2channels( int mode ) XINE_PROTECTED; -/* - * converts the number of channels into the audio output mode - */ -int _x_ao_channels2mode( int channels ) XINE_PROTECTED; - -#define AO_CAP_MIXER_VOL 0x00000100 /* driver supports mixer control */ -#define AO_CAP_PCM_VOL 0x00000200 /* driver supports pcm control */ -#define AO_CAP_MUTE_VOL 0x00000400 /* driver can mute volume */ -#define AO_CAP_8BITS 0x00000800 /* driver support 8-bit samples */ -#define AO_CAP_16BITS 0x00001000 /* driver support 16-bit samples */ -#define AO_CAP_24BITS 0x00002000 /* driver support 24-bit samples */ -#define AO_CAP_FLOAT32 0x00004000 /* driver support 32-bit samples. i.e. Floats */ - -/* properties supported by get/set_property() */ -#define AO_PROP_MIXER_VOL 0 -#define AO_PROP_PCM_VOL 1 -#define AO_PROP_MUTE_VOL 2 -#define AO_PROP_COMPRESSOR 3 -#define AO_PROP_DISCARD_BUFFERS 4 -#define AO_PROP_BUFS_IN_FIFO 5 /* read-only */ -#define AO_PROP_AMP 6 /* amplifier */ -#define AO_PROP_EQ_30HZ 7 /* equalizer */ -#define AO_PROP_EQ_60HZ 8 /* equalizer */ -#define AO_PROP_EQ_125HZ 9 /* equalizer */ -#define AO_PROP_EQ_250HZ 10 /* equalizer */ -#define AO_PROP_EQ_500HZ 11 /* equalizer */ -#define AO_PROP_EQ_1000HZ 12 /* equalizer */ -#define AO_PROP_EQ_2000HZ 13 /* equalizer */ -#define AO_PROP_EQ_4000HZ 14 /* equalizer */ -#define AO_PROP_EQ_8000HZ 15 /* equalizer */ -#define AO_PROP_EQ_16000HZ 16 /* equalizer */ -#define AO_PROP_CLOSE_DEVICE 17 /* force closing audio device */ -#define AO_PROP_AMP_MUTE 18 /* amplifier mute */ -#define AO_PROP_NUM_STREAMS 19 /* read-only */ -#define AO_PROP_CLOCK_SPEED 20 /* inform audio_out that speed has changed */ -#define AO_NUM_PROPERTIES 21 - -/* audio device control ops */ -#define AO_CTRL_PLAY_PAUSE 0 -#define AO_CTRL_PLAY_RESUME 1 -#define AO_CTRL_FLUSH_BUFFERS 2 - -/* above that value audio frames are discarded */ -#define AO_MAX_GAP 15000 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/broadcaster.h b/src/xine-engine/broadcaster.h deleted file mode 100644 index 093fb4af0..000000000 --- a/src/xine-engine/broadcaster.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * broadcaster.h - */ - -#ifndef HAVE_BROADCASTER_H -#define HAVE_BROADCASTER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -typedef struct broadcaster_s broadcaster_t; - -broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_PROTECTED; -void _x_close_broadcaster(broadcaster_t *this) XINE_PROTECTED; -int _x_get_broadcaster_port(broadcaster_t *this) XINE_PROTECTED; - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h deleted file mode 100644 index ce209c9da..000000000 --- a/src/xine-engine/buffer.h +++ /dev/null @@ -1,718 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * - * contents: - * - * buffer_entry structure - serves as a transport encapsulation - * of the mpeg audio/video data through xine - * - * free buffer pool management routines - * - * FIFO buffer structures/routines - */ - -#ifndef HAVE_BUFFER_H -#define HAVE_BUFFER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#ifdef XINE_COMPILE -# include -# include "attributes.h" -#else -# include -# include -#endif - -#define BUF_MAX_CALLBACKS 5 - -/** - * @defgroup buffer_types Buffer Types - * - * a buffer type ID describes the contents of a buffer - * it consists of three fields: - * - * buf_type = 0xMMDDCCCC - * - * MM : major buffer type (CONTROL, VIDEO, AUDIO, SPU) - * DD : decoder selection (e.g. MPEG, OPENDIVX ... for VIDEO) - * CCCC : channel number or other subtype information for the decoder - */ -/*@{*/ - -#define BUF_MAJOR_MASK 0xFF000000 -#define BUF_DECODER_MASK 0x00FF0000 - -/** - * @defgroup buffer_ctrl Control buffer types - */ -/*@{*/ -#define BUF_CONTROL_BASE 0x01000000 -#define BUF_CONTROL_START 0x01000000 -#define BUF_CONTROL_END 0x01010000 -#define BUF_CONTROL_QUIT 0x01020000 -#define BUF_CONTROL_DISCONTINUITY 0x01030000 /**< former AVSYNC_RESET */ -#define BUF_CONTROL_NOP 0x01040000 -#define BUF_CONTROL_AUDIO_CHANNEL 0x01050000 -#define BUF_CONTROL_SPU_CHANNEL 0x01060000 -#define BUF_CONTROL_NEWPTS 0x01070000 -#define BUF_CONTROL_RESET_DECODER 0x01080000 -#define BUF_CONTROL_HEADERS_DONE 0x01090000 -#define BUF_CONTROL_FLUSH_DECODER 0x010a0000 -#define BUF_CONTROL_RESET_TRACK_MAP 0x010b0000 -/*@}*/ - -/** - * @defgroup buffer_video Video buffer types - * @note (please keep in sync with buffer_types.c) - */ -/*@{*/ -#define BUF_VIDEO_BASE 0x02000000 -#define BUF_VIDEO_UNKNOWN 0x02ff0000 /**< no decoder should handle this one */ -#define BUF_VIDEO_MPEG 0x02000000 -#define BUF_VIDEO_MPEG4 0x02010000 -#define BUF_VIDEO_CINEPAK 0x02020000 -#define BUF_VIDEO_SORENSON_V1 0x02030000 -#define BUF_VIDEO_MSMPEG4_V2 0x02040000 -#define BUF_VIDEO_MSMPEG4_V3 0x02050000 -#define BUF_VIDEO_MJPEG 0x02060000 -#define BUF_VIDEO_IV50 0x02070000 -#define BUF_VIDEO_IV41 0x02080000 -#define BUF_VIDEO_IV32 0x02090000 -#define BUF_VIDEO_IV31 0x020a0000 -#define BUF_VIDEO_ATIVCR1 0x020b0000 -#define BUF_VIDEO_ATIVCR2 0x020c0000 -#define BUF_VIDEO_I263 0x020d0000 -#define BUF_VIDEO_RV10 0x020e0000 -#define BUF_VIDEO_RGB 0x02100000 -#define BUF_VIDEO_YUY2 0x02110000 -#define BUF_VIDEO_JPEG 0x02120000 -#define BUF_VIDEO_WMV7 0x02130000 -#define BUF_VIDEO_WMV8 0x02140000 -#define BUF_VIDEO_MSVC 0x02150000 -#define BUF_VIDEO_DV 0x02160000 -#define BUF_VIDEO_REAL 0x02170000 -#define BUF_VIDEO_VP31 0x02180000 -#define BUF_VIDEO_H263 0x02190000 -#define BUF_VIDEO_3IVX 0x021A0000 -#define BUF_VIDEO_CYUV 0x021B0000 -#define BUF_VIDEO_DIVX5 0x021C0000 -#define BUF_VIDEO_XVID 0x021D0000 -#define BUF_VIDEO_SMC 0x021E0000 -#define BUF_VIDEO_RPZA 0x021F0000 -#define BUF_VIDEO_QTRLE 0x02200000 -#define BUF_VIDEO_MSRLE 0x02210000 -#define BUF_VIDEO_DUCKTM1 0x02220000 -#define BUF_VIDEO_FLI 0x02230000 -#define BUF_VIDEO_ROQ 0x02240000 -#define BUF_VIDEO_SORENSON_V3 0x02250000 -#define BUF_VIDEO_MSMPEG4_V1 0x02260000 -#define BUF_VIDEO_MSS1 0x02270000 -#define BUF_VIDEO_IDCIN 0x02280000 -#define BUF_VIDEO_PGVV 0x02290000 -#define BUF_VIDEO_ZYGO 0x022A0000 -#define BUF_VIDEO_TSCC 0x022B0000 -#define BUF_VIDEO_YVU9 0x022C0000 -#define BUF_VIDEO_VQA 0x022D0000 -#define BUF_VIDEO_GREY 0x022E0000 -#define BUF_VIDEO_XXAN 0x022F0000 -#define BUF_VIDEO_WC3 0x02300000 -#define BUF_VIDEO_YV12 0x02310000 -#define BUF_VIDEO_SEGA 0x02320000 -#define BUF_VIDEO_RV20 0x02330000 -#define BUF_VIDEO_RV30 0x02340000 -#define BUF_VIDEO_MVI2 0x02350000 -#define BUF_VIDEO_UCOD 0x02360000 -#define BUF_VIDEO_WMV9 0x02370000 -#define BUF_VIDEO_INTERPLAY 0x02380000 -#define BUF_VIDEO_RV40 0x02390000 -#define BUF_VIDEO_PSX_MDEC 0x023A0000 -#define BUF_VIDEO_YUV_FRAMES 0x023B0000 /**< uncompressed YUV, delivered by v4l input plugin */ -#define BUF_VIDEO_HUFFYUV 0x023C0000 -#define BUF_VIDEO_IMAGE 0x023D0000 -#define BUF_VIDEO_THEORA 0x023E0000 -#define BUF_VIDEO_4XM 0x023F0000 -#define BUF_VIDEO_I420 0x02400000 -#define BUF_VIDEO_VP4 0x02410000 -#define BUF_VIDEO_VP5 0x02420000 -#define BUF_VIDEO_VP6 0x02430000 -#define BUF_VIDEO_VMD 0x02440000 -#define BUF_VIDEO_MSZH 0x02450000 -#define BUF_VIDEO_ZLIB 0x02460000 -#define BUF_VIDEO_8BPS 0x02470000 -#define BUF_VIDEO_ASV1 0x02480000 -#define BUF_VIDEO_ASV2 0x02490000 -#define BUF_VIDEO_BITPLANE 0x024A0000 /**< Amiga typical picture and animation format */ -#define BUF_VIDEO_BITPLANE_BR1 0x024B0000 /**< the same with Bytrun compression 1 */ -#define BUF_VIDEO_FLV1 0x024C0000 -#define BUF_VIDEO_H264 0x024D0000 -#define BUF_VIDEO_MJPEG_B 0x024E0000 -#define BUF_VIDEO_H261 0x024F0000 -#define BUF_VIDEO_AASC 0x02500000 -#define BUF_VIDEO_LOCO 0x02510000 -#define BUF_VIDEO_QDRW 0x02520000 -#define BUF_VIDEO_QPEG 0x02530000 -#define BUF_VIDEO_ULTI 0x02540000 -#define BUF_VIDEO_WNV1 0x02550000 -#define BUF_VIDEO_XL 0x02560000 -#define BUF_VIDEO_RT21 0x02570000 -#define BUF_VIDEO_FPS1 0x02580000 -#define BUF_VIDEO_DUCKTM2 0x02590000 -#define BUF_VIDEO_CSCD 0x025A0000 -#define BUF_VIDEO_ALGMM 0x025B0000 -#define BUF_VIDEO_ZMBV 0x025C0000 -#define BUF_VIDEO_AVS 0x025D0000 -#define BUF_VIDEO_SMACKER 0x025E0000 -#define BUF_VIDEO_NUV 0x025F0000 -#define BUF_VIDEO_KMVC 0x02600000 -#define BUF_VIDEO_FLASHSV 0x02610000 -#define BUF_VIDEO_CAVS 0x02620000 -#define BUF_VIDEO_VP6F 0x02630000 -#define BUF_VIDEO_THEORA_RAW 0x02640000 -#define BUF_VIDEO_VC1 0x02650000 -/*@}*/ - -/** - * @defgroup buffer_audio Audio buffer types - * @note (please keep in sync with buffer_types.c) - */ -/*@{*/ -#define BUF_AUDIO_BASE 0x03000000 -#define BUF_AUDIO_UNKNOWN 0x03ff0000 /**< no decoder should handle this one */ -#define BUF_AUDIO_A52 0x03000000 -#define BUF_AUDIO_MPEG 0x03010000 -#define BUF_AUDIO_LPCM_BE 0x03020000 -#define BUF_AUDIO_LPCM_LE 0x03030000 -#define BUF_AUDIO_WMAV1 0x03040000 -#define BUF_AUDIO_DTS 0x03050000 -#define BUF_AUDIO_MSADPCM 0x03060000 -#define BUF_AUDIO_MSIMAADPCM 0x03070000 -#define BUF_AUDIO_MSGSM 0x03080000 -#define BUF_AUDIO_VORBIS 0x03090000 -#define BUF_AUDIO_IMC 0x030a0000 -#define BUF_AUDIO_LH 0x030b0000 -#define BUF_AUDIO_VOXWARE 0x030c0000 -#define BUF_AUDIO_ACELPNET 0x030d0000 -#define BUF_AUDIO_AAC 0x030e0000 -#define BUF_AUDIO_DNET 0x030f0000 -#define BUF_AUDIO_VIVOG723 0x03100000 -#define BUF_AUDIO_DK3ADPCM 0x03110000 -#define BUF_AUDIO_DK4ADPCM 0x03120000 -#define BUF_AUDIO_ROQ 0x03130000 -#define BUF_AUDIO_QTIMAADPCM 0x03140000 -#define BUF_AUDIO_MAC3 0x03150000 -#define BUF_AUDIO_MAC6 0x03160000 -#define BUF_AUDIO_QDESIGN1 0x03170000 -#define BUF_AUDIO_QDESIGN2 0x03180000 -#define BUF_AUDIO_QCLP 0x03190000 -#define BUF_AUDIO_SMJPEG_IMA 0x031A0000 -#define BUF_AUDIO_VQA_IMA 0x031B0000 -#define BUF_AUDIO_MULAW 0x031C0000 -#define BUF_AUDIO_ALAW 0x031D0000 -#define BUF_AUDIO_GSM610 0x031E0000 -#define BUF_AUDIO_EA_ADPCM 0x031F0000 -#define BUF_AUDIO_WMAV2 0x03200000 -#define BUF_AUDIO_COOK 0x03210000 -#define BUF_AUDIO_ATRK 0x03220000 -#define BUF_AUDIO_14_4 0x03230000 -#define BUF_AUDIO_28_8 0x03240000 -#define BUF_AUDIO_SIPRO 0x03250000 -#define BUF_AUDIO_WMAV3 0x03260000 -#define BUF_AUDIO_INTERPLAY 0x03270000 -#define BUF_AUDIO_XA_ADPCM 0x03280000 -#define BUF_AUDIO_WESTWOOD 0x03290000 -#define BUF_AUDIO_DIALOGIC_IMA 0x032A0000 -#define BUF_AUDIO_NSF 0x032B0000 -#define BUF_AUDIO_FLAC 0x032C0000 -#define BUF_AUDIO_DV 0x032D0000 -#define BUF_AUDIO_WMAV 0x032E0000 -#define BUF_AUDIO_SPEEX 0x032F0000 -#define BUF_AUDIO_RAWPCM 0x03300000 -#define BUF_AUDIO_4X_ADPCM 0x03310000 -#define BUF_AUDIO_VMD 0x03320000 -#define BUF_AUDIO_XAN_DPCM 0x03330000 -#define BUF_AUDIO_ALAC 0x03340000 -#define BUF_AUDIO_MPC 0x03350000 -#define BUF_AUDIO_SHORTEN 0x03360000 -#define BUF_AUDIO_WESTWOOD_SND1 0x03370000 -#define BUF_AUDIO_WMALL 0x03380000 -#define BUF_AUDIO_TRUESPEECH 0x03390000 -#define BUF_AUDIO_TTA 0x033A0000 -#define BUF_AUDIO_SMACKER 0x033B0000 -#define BUF_AUDIO_FLVADPCM 0x033C0000 -#define BUF_AUDIO_WAVPACK 0x033D0000 -/*@}*/ - -/** - * @defgroup buffer_spu SPU buffer types - */ -/*@{*/ -#define BUF_SPU_BASE 0x04000000 -#define BUF_SPU_DVD 0x04000000 -#define BUF_SPU_TEXT 0x04010000 -#define BUF_SPU_CC 0x04020000 -#define BUF_SPU_DVB 0x04030000 -#define BUF_SPU_SVCD 0x04040000 -#define BUF_SPU_CVD 0x04050000 -#define BUF_SPU_OGM 0x04060000 -#define BUF_SPU_CMML 0x04070000 -/*@}*/ - -/** - * @defgroup buffer_demux Demuxer block types - */ -/*@{*/ -#define BUF_DEMUX_BLOCK 0x05000000 -/*@}*/ - -/*@}*/ - -typedef struct extra_info_s extra_info_t; - -/** - * @brief Structure to pass information from input or demuxer plugins - * to output frames (past decoder). - * - * New data must be added after the existing fields to not break ABI - * (backward compatibility). - */ - -struct extra_info_s { - - int input_normpos; /**< remember where this buf came from in - * the input source (0..65535). can be - * either time or offset based. */ - int input_time; /**< time offset in miliseconds from - * beginning of stream */ - uint32_t frame_number; /**< number of current frame if known */ - - int seek_count; /**< internal engine use */ - int64_t vpts; /**< set on output layers only */ - - int invalid; /**< do not use this extra info to update anything */ - int total_time; /**< duration in miliseconds of the stream */ -}; - - -#define BUF_NUM_DEC_INFO 5 - -typedef struct buf_element_s buf_element_t; -struct buf_element_s { - buf_element_t *next; - - unsigned char *mem; - unsigned char *content; /**< start of raw content in mem (without header etc) */ - - int32_t size ; /**< size of _content_ */ - int32_t max_size; /**< size of pre-allocated memory pointed to by "mem" */ - int64_t pts; /**< presentation time stamp, used for a/v sync */ - int64_t disc_off; /**< discontinuity offset */ - - extra_info_t *extra_info; /**< extra info will be passed to frames */ - - uint32_t decoder_flags; /**< stuff like keyframe, is_header ... see below */ - - /** additional decoder flags and other dec-spec. stuff */ - uint32_t decoder_info[BUF_NUM_DEC_INFO]; - /** pointers to dec-spec. stuff */ - void *decoder_info_ptr[BUF_NUM_DEC_INFO]; - - void (*free_buffer) (buf_element_t *buf); - - void *source; /**< pointer to source of this buffer for - * free_buffer */ - - uint32_t type; -} ; - -/** keyframe should be set whenever possible (that is, when demuxer - * knows about frames and keyframes). */ -#define BUF_FLAG_KEYFRAME 0x0001 - -/** frame start/end. BUF_FLAG_FRAME_END is sent on last buf of a frame */ -#define BUF_FLAG_FRAME_START 0x0002 -#define BUF_FLAG_FRAME_END 0x0004 - -/** any out-of-band data needed to initialize decoder must have - * this flag set. */ -#define BUF_FLAG_HEADER 0x0008 - -/** preview buffers are normal data buffers that must not produce any - * output in decoders (may be used to sneak details about the stream - * to come). */ -#define BUF_FLAG_PREVIEW 0x0010 - -/** set when user stop the playback */ -#define BUF_FLAG_END_USER 0x0020 - -/** set when stream finished naturaly */ -#define BUF_FLAG_END_STREAM 0x0040 - -/** decoder_info[0] carries the frame step (1/90000). */ -#define BUF_FLAG_FRAMERATE 0x0080 - -/** hint to metronom that seeking has occurred */ -#define BUF_FLAG_SEEK 0x0100 - -/** special information inside, see below. */ -#define BUF_FLAG_SPECIAL 0x0200 - -/** header use standard xine_bmiheader or xine_waveformatex structs. - * xine_waveformatex is actually optional since the most important - * information for audio init is available from decoder_info[]. - * note: BUF_FLAG_HEADER must also be set. */ -#define BUF_FLAG_STDHEADER 0x0400 - -/** decoder_info[1] carries numerator for display aspect ratio - * decoder_info[2] carries denominator for display aspect ratio */ -#define BUF_FLAG_ASPECT 0x0800 - - -/** - * \defgroup buffer_special Special buffer types: - * Sometimes there is a need to relay special information from a demuxer - * to a video decoder. For example, some file types store palette data in - * the file header independant of the video data. The special buffer type - * offers a way to communicate this or any other custom, format-specific - * data to the decoder. - * - * The interface was designed in a way that did not require an API - * version bump. To send a special buffer type, set a buffer's flags field - * to BUF_FLAG_SPECIAL. Set the buffer's decoder_info[1] field to a - * number according to one of the special buffer subtypes defined below. - * The second and third decoder_info[] fields are defined according to - * your buffer type's requirements. - * - * Finally, remember to set the buffer's size to 0. This way, if a special - * buffer is sent to a decode that does not know how to handle it, the - * buffer will fall through to the case where the buffer's data content - * is accumulated and no harm will be done. - */ -/*@{*/ - -/** - * In a BUF_SPECIAL_PALETTE buffer: - * decoder_info[1] = BUF_SPECIAL_PALETTE - * decoder_info[2] = number of entries in palette table - * decoder_info_ptr[2] = pointer to palette table - * This buffer type is used to provide a file- and decoder-independent - * facility to transport RGB color palettes from demuxers to decoders. - * A palette table is an array of palette_entry_t structures. A decoder - * should not count on this array to exist for the duration of the - * program's execution and should copy, manipulate, and store the palette - * data privately if it needs the palette information. - */ -#define BUF_SPECIAL_PALETTE 1 - - -/* special buffer type 2 used to be defined but is now available for use */ - - -/** - * In a BUF_SPECIAL_ASPECT buffer: - * decoder_info[1] = BUF_SPECIAL_ASPECT - * decoder_info[2] = MPEG2 aspect ratio code - * decoder_info[3] = stream scale prohibitions - * This buffer is used to force mpeg decoders to use a certain aspect. - * Currently xine-dvdnav uses this, because it has more accurate information - * about the aspect from the dvd ifo-data. - * The stream scale prohibitions are also delivered, with bit 0 meaning - * "deny letterboxing" and bit 1 meaning "deny pan&scan" - */ -#define BUF_SPECIAL_ASPECT 3 - -/** - * In a BUF_SPECIAL_DECODER_CONFIG buffer: - * decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG - * decoder_info[2] = data size - * decoder_info_ptr[2] = pointer to data - * This buffer is used to pass config information from .mp4 files - * (atom esds) to decoders. both mpeg4 and aac streams use that. - */ -#define BUF_SPECIAL_DECODER_CONFIG 4 - -/** - * In a BUF_SPECIAL_STSD_ATOM buffer: - * decoder_info[1] = BUF_SPECIAL_STSD_ATOM - * decoder_info[2] = size of the ImageDescription atom, minus the - * four length bytes at the beginning - * decoder_info_ptr[2] = pointer to ImageDescription atom, starting with - * the codec fourcc - * Some Quicktime decoders need information contained within the - * ImageDescription atom inside a Quicktime file's stsd atom. This - * special buffer carries the ImageDescription atom from the QT demuxer - * to an A/V decoder. - */ -#define BUF_SPECIAL_STSD_ATOM 5 - -/** - * In a BUF_SPECIAL_LPCM_CONFIG buffer: - * decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG - * decoder_info[2] = config data - * lpcm data encoded into mpeg2 streams have a format configuration - * byte in every frame. this is used to detect the sample rate, - * number of bits and channels. - */ -#define BUF_SPECIAL_LPCM_CONFIG 6 - -/** - * In a BUF_SPECIAL_CHARSET_ENCODING buffer: - * decoder_info[1] = BUF_SPECIAL_CHARSET_ENCODING - * decoder_info[2] = size of charset encoding string - * decoder_info_ptr[2] = pointer to charset encoding string - * This is used mostly with subtitle buffers when encoding is - * known at demuxer level (take precedence over xine config - * settings such as subtitles.separate.src_encoding) - */ -#define BUF_SPECIAL_CHARSET_ENCODING 7 - - -/** - * In a BUF_SPECIAL_SPU_DVD_SUBTYPE: - * decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE - * decoder_info[2] = subtype - * decoder_info[3] = - * This buffer is pass SPU subtypes from DVDs - */ -#define BUF_SPECIAL_SPU_DVD_SUBTYPE 8 - - -#define SPU_DVD_SUBTYPE_CLUT 1 -#define SPU_DVD_SUBTYPE_PACKAGE 2 -#define SPU_DVD_SUBTYPE_VOBSUB_PACKAGE 3 -#define SPU_DVD_SUBTYPE_NAV 4 - -/** - * In a BUF_SPECIAL_SPU_DVB_DESCRIPTOR - * decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR - * decoder_info[2] = size of spu_dvb_descriptor_t - * decoder_info_ptr[2] = pointer to spu_dvb_descriptor_t, or NULL - * decoder_info[3] = - * - * This buffer is used to tell a DVBSUB decoder when the stream - * changes. For more information on how to write a DVBSUB decoder, - * see the comment at the top of src/demuxers/demux_ts.c - **/ -#define BUF_SPECIAL_SPU_DVB_DESCRIPTOR 9 - -/** - * In a BUF_SPECIAL_RV_CHUNK_TABLE: - * decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE - * decoder_info[2] = number of entries in chunk table - * decoder_info_ptr[2] = pointer to the chunk table - * - * This buffer transports the chunk table associated to each RealVideo frame. - */ -#define BUF_SPECIAL_RV_CHUNK_TABLE 10 -/*@}*/ - -typedef struct spu_dvb_descriptor_s spu_dvb_descriptor_t; -struct spu_dvb_descriptor_s -{ - char lang[4]; - long comp_page_id; - long aux_page_id; -} ; - -typedef struct palette_entry_s palette_entry_t; -struct palette_entry_s -{ - unsigned char r, g, b; -} ; - -typedef struct fifo_buffer_s fifo_buffer_t; -struct fifo_buffer_s -{ - buf_element_t *first, *last; - - int fifo_size; - uint32_t fifo_data_size; - void *fifo_empty_cb_data; - - pthread_mutex_t mutex; - pthread_cond_t not_empty; - - /* - * functions to access this fifo: - */ - - void (*put) (fifo_buffer_t *fifo, buf_element_t *buf); - - buf_element_t *(*get) (fifo_buffer_t *fifo); - - void (*clear) (fifo_buffer_t *fifo) ; - - int (*size) (fifo_buffer_t *fifo); - - int (*num_free) (fifo_buffer_t *fifo); - - uint32_t (*data_size) (fifo_buffer_t *fifo); - - void (*dispose) (fifo_buffer_t *fifo); - - /* - * alloc buffer for this fifo from global buf pool - * you don't have to use this function to allocate a buffer, - * an input plugin can decide to implement it's own - * buffer allocation functions - */ - - buf_element_t *(*buffer_pool_alloc) (fifo_buffer_t *self); - - - /* - * special functions, not used by demuxers - */ - - /* the same as buffer_pool_alloc but may fail if none is available */ - buf_element_t *(*buffer_pool_try_alloc) (fifo_buffer_t *self); - - /* the same as put but insert at the head of the fifo */ - void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf); - - /* callbacks */ - void (*register_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *), void *cb_data); - void (*register_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); - void (*register_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); - void (*unregister_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *)); - void (*unregister_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *)); - void (*unregister_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *)); - - /* - * private variables for buffer pool management - */ - buf_element_t *buffer_pool_top; /* a stack actually */ - pthread_mutex_t buffer_pool_mutex; - pthread_cond_t buffer_pool_cond_not_empty; - int buffer_pool_num_free; - int buffer_pool_capacity; - int buffer_pool_buf_size; - void *buffer_pool_base; /*used to free mem chunk */ - void (*alloc_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, void *data_cb); - void (*put_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); - void (*get_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); - void *alloc_cb_data[BUF_MAX_CALLBACKS]; - void *put_cb_data[BUF_MAX_CALLBACKS]; - void *get_cb_data[BUF_MAX_CALLBACKS]; -} ; - -/** - * @brief Allocate and initialise new (empty) FIFO buffers. - * @param num_buffer Number of buffers to allocate. - * @param buf_size Size of each buffer. - * @internal Only used by video and audio decoder loops. - */ -fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size); - -/** - * @brief Allocate and initialise new dummy FIFO buffers. - * @param num_buffer Number of dummy buffers to allocate. - * @param buf_size Size of each buffer. - * @internal Only used by video and audio decoder loops. - */ -fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size); - - -/** - * @brief Returns the \ref buffer_video "BUF_VIDEO_xxx" for the given fourcc. - * @param fourcc_int 32-bit FOURCC value in machine endianness - * @sa _x_formattag_to_buf_audio - * - * example: fourcc_int = *(uint32_t *)fourcc_char; - */ -uint32_t _x_fourcc_to_buf_video( uint32_t fourcc_int ) XINE_PROTECTED; - -/** - * @brief Returns video codec name given the buffer type. - * @param buf_type One of the \ref buffer_video "BUF_VIDEO_xxx" values. - * @sa _x_buf_audio_name - */ -const char *_x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED; - -/** - * @brief Returns the \ref buffer_audio "BUF_AUDIO_xxx" for the given formattag. - * @param formattagg 32-bit format tag value in machine endianness - * @sa _x_fourcc_to_buf_video - */ -uint32_t _x_formattag_to_buf_audio( uint32_t formattag ) XINE_PROTECTED; - -/** - * @brief Returns audio codec name given the buffer type. - * @param buf_type One of the \ref buffer_audio "BUF_AUDIO_xxx" values. - * @sa _x_buf_video_name - */ -const char *_x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED; - - -/** - * @brief xine version of BITMAPINFOHEADER. - * @note Should be safe to compile on 64bits machines. - * @note Will always use machine endian format, so demuxers reading - * stuff from win32 formats must use the function below. - */ -typedef struct XINE_PACKED { - int32_t biSize; - int32_t biWidth; - int32_t biHeight; - int16_t biPlanes; - int16_t biBitCount; - uint32_t biCompression; - int32_t biSizeImage; - int32_t biXPelsPerMeter; - int32_t biYPelsPerMeter; - int32_t biClrUsed; - int32_t biClrImportant; -} xine_bmiheader; - -/** - * @brief xine version of WAVEFORMATEX. - * @note The same comments from xine_bmiheader applies. - */ -typedef struct XINE_PACKED { - int16_t wFormatTag; - int16_t nChannels; - int32_t nSamplesPerSec; - int32_t nAvgBytesPerSec; - int16_t nBlockAlign; - int16_t wBitsPerSample; - int16_t cbSize; -} xine_waveformatex; - -/** Convert xine_bmiheader struct from little endian */ -void _x_bmiheader_le2me( xine_bmiheader *bih ) XINE_PROTECTED; - -/** Convert xine_waveformatex struct from little endian */ -void _x_waveformatex_le2me( xine_waveformatex *wavex ) XINE_PROTECTED; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h deleted file mode 100644 index 22a544c00..000000000 --- a/src/xine-engine/configfile.h +++ /dev/null @@ -1,218 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * config file management - */ - -#ifndef HAVE_CONFIGFILE_H -#define HAVE_CONFIGFILE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef XINE_COMPILE -# include "xine.h" -#else -# include -#endif - -#define CONFIG_FILE_VERSION 2 - -/** - * config entries above this experience - * level must never be changed from MRL - */ -#define XINE_CONFIG_SECURITY 30 - - -typedef struct cfg_entry_s cfg_entry_t; -typedef struct config_values_s config_values_t; - -struct cfg_entry_s { - cfg_entry_t *next; - config_values_t *config; - - char *key; - int type; - - /** user experience level */ - int exp_level; - - /** type unknown */ - char *unknown_value; - - /** type string */ - char *str_value; - char *str_default; - - /** common to range, enum, num, bool: */ - int num_value; - int num_default; - - /** type range specific: */ - int range_min; - int range_max; - - /** type enum specific: */ - char **enum_values; - - /** help info for the user */ - char *description; - char *help; - - /** callback function and data for live changeable values */ - xine_config_cb_t callback; - void *callback_data; -}; - -struct config_values_s { - - /* - * register config values - * - * these functions return the current value of the - * registered item, i.e. the default value if it was - * not found in the config file or the current value - * from the config file otherwise - */ - - char* (*register_string) (config_values_t *self, - const char *key, - const char *def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - char* (*register_filename) (config_values_t *self, - const char *key, - const char *def_value, - int req_type, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_range) (config_values_t *self, - const char *key, - int def_value, - int min, int max, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_enum) (config_values_t *self, - const char *key, - int def_value, - char **values, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_num) (config_values_t *self, - const char *key, - int def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_bool) (config_values_t *self, - const char *key, - int def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - /** convenience function to update range, enum, num and bool values */ - void (*update_num) (config_values_t *self, const char *key, int value); - - /** convenience function to update string values */ - void (*update_string) (config_values_t *self, const char *key, const char *value); - - /** small utility function for enum handling */ - int (*parse_enum) (const char *str, const char **values); - - /** - * @brief lookup config entries - * - * remember to call the changed_cb if it exists - * and you changed the value of this item - */ - - cfg_entry_t* (*lookup_entry) (config_values_t *self, const char *key); - - /** - * unregister callback function - */ - void (*unregister_callback) (config_values_t *self, const char *key); - - /** - * dispose of all config entries in memory - */ - void (*dispose) (config_values_t *self); - - /* - * config values are stored here: - */ - cfg_entry_t *first, *last, *cur; - - /** - * mutex for modification to the config - */ - pthread_mutex_t config_lock; - - /** - * current config file's version number - */ - int current_version; -}; - -/** - * @brief allocate and init a new xine config object - * @internal - */ -config_values_t *_x_config_init (void); - -/** - * @brief interpret stream_setup part of mrls for config value changes - * @internal - */ - -int _x_config_change_opt(config_values_t *config, const char *opt); - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/info_helper.h b/src/xine-engine/info_helper.h deleted file mode 100644 index d4123ba2b..000000000 --- a/src/xine-engine/info_helper.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stream metainfo helper functions - * hide some xine engine details from demuxers and reduce code duplication - * - * $id$ - */ - -#ifndef INFO_HELPER_H -#define INFO_HELPER_H - -#include -#include "xine_internal.h" - -/* - * set a stream info - * - * params: - * *stream the xine stream - * info stream info id (see xine.h, XINE_STREAM_INFO_*) - * value the value to assign - * - */ -void _x_stream_info_set(xine_stream_t *stream, int info, int value) XINE_PROTECTED; - -/* - * reset a stream info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -void _x_stream_info_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * reset a stream info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -void _x_stream_info_public_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -uint32_t _x_stream_info_get(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -uint32_t _x_stream_info_get_public(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *str null-terminated string (using current locale) - * - */ -void _x_meta_info_set(xine_stream_t *stream, int info, const char *str) XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *str null-terminated string (using utf8) - * - */ -void _x_meta_info_set_utf8(xine_stream_t *stream, int info, const char *str) XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *str null-terminated string (using encoding below) - * *enc charset encoding of the string - * - */ -void _x_meta_info_set_generic(xine_stream_t *stream, int info, const char *str, const char *enc) XINE_PROTECTED; - -/* - * set a stream meta multiple info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * ... one or more meta info, followed by a NULL pointer - * - */ -void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) XINE_SENTINEL XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *buf char buffer (not a null-terminated string) - * len length of the metainfo - * - */ -void _x_meta_info_n_set(xine_stream_t *stream, int info, const char *buf, int len) XINE_PROTECTED; - -/* - * reset a stream meta info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -void _x_meta_info_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * reset a stream meta info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -void _x_meta_info_public_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream meta info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -const char *_x_meta_info_get(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream meta info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -const char *_x_meta_info_get_public(xine_stream_t *stream, int info) XINE_PROTECTED; - -#endif /* INFO_HELPER_H */ diff --git a/src/xine-engine/io_helper.h b/src/xine-engine/io_helper.h deleted file mode 100644 index 0aac8fcfc..000000000 --- a/src/xine-engine/io_helper.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * abortable i/o helper functions - */ - -#ifndef IO_HELPER_H -#define IO_HELPER_H - -#include "xine_internal.h" - - -/* select states */ -#define XIO_READ_READY 1 -#define XIO_WRITE_READY 2 - -/* xine select return codes */ -#define XIO_READY 0 -#define XIO_ERROR 1 -#define XIO_ABORTED 2 -#define XIO_TIMEOUT 3 - - -/* - * Waits for a file descriptor/socket to change status. - * - * network input plugins should use this function in order to - * not freeze the engine. - * - * params : - * stream needed for aborting and reporting errors but may be NULL - * fd file/socket descriptor - * state XIO_READ_READY, XIO_WRITE_READY - * timeout_sec timeout in seconds - * - * An other thread can abort this function if stream != NULL by setting - * stream->demux_action_pending. - * - * return value : - * XIO_READY the file descriptor is ready for cmd - * XIO_ERROR an i/o error occured - * XIO_ABORTED command aborted by an other thread - * XIO_TIMEOUT the file descriptor is not ready after timeout_msec milliseconds - */ -int _x_io_select (xine_stream_t *stream, int fd, int state, int timeout_msec) XINE_PROTECTED; - - -/* - * open a tcp connection - * - * params : - * stream needed for reporting errors but may be NULL - * host address of target - * port port on target - * - * returns a socket descriptor or -1 if an error occured - */ -int _x_io_tcp_connect(xine_stream_t *stream, const char *host, int port) XINE_PROTECTED; - -/* - * wait for finish connection - * - * params : - * stream needed for aborting and reporting errors but may be NULL - * fd socket descriptor - * timeout_msec timeout in milliseconds - * - * return value: - * XIO_READY host respond, the socket is ready for cmd - * XIO_ERROR an i/o error occured - * XIO_ABORTED command aborted by an other thread - * XIO_TIMEOUT the file descriptor is not ready after timeout - */ -int _x_io_tcp_connect_finish(xine_stream_t *stream, int fd, int timeout_msec) XINE_PROTECTED; - -/* - * read from tcp socket checking demux_action_pending - * - * network input plugins should use this function in order to - * not freeze the engine. - * - * aborts with zero if no data is available and *abort is set - */ -off_t _x_io_tcp_read (xine_stream_t *stream, int s, void *buf, off_t todo) XINE_PROTECTED; - - -/* - * write to a tcp socket checking demux_action_pending - * - * network input plugins should use this function in order to - * not freeze the engine. - * - * aborts with zero if no data is available and *abort is set - */ -off_t _x_io_tcp_write (xine_stream_t *stream, int s, void *buf, off_t todo) XINE_PROTECTED; - -/* - * read from a file descriptor checking demux_action_pending - * - * the fifo input plugin should use this function in order to - * not freeze the engine. - * - * aborts with zero if no data is available and *abort is set - */ -off_t _x_io_file_read (xine_stream_t *stream, int fd, void *buf, off_t todo) XINE_PROTECTED; - - -/* - * write to a file descriptor checking demux_action_pending - * - * the fifo input plugin should use this function in order to - * not freeze the engine. - * - * aborts with zero if *abort is set - */ -off_t _x_io_file_write (xine_stream_t *stream, int fd, void *buf, off_t todo) XINE_PROTECTED; - -/* - * read a string from socket, return string length (same as strlen) - * the string is always '\0' terminated but given buffer size is never exceeded - * that is, _x_io_tcp_read_line(,,,X) <= (X-1) ; X > 0 - */ -int _x_io_tcp_read_line(xine_stream_t *stream, int sock, char *str, int size) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h deleted file mode 100644 index 77919f16e..000000000 --- a/src/xine-engine/metronom.h +++ /dev/null @@ -1,364 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * metronom: general pts => virtual calculation/assoc - * - * virtual pts: unit 1/90000 sec, always increasing - * can be used for synchronization - * video/audio frame with same pts also have same vpts - * but pts is likely to differ from vpts - * - * the basic idea is: - * video_pts + video_wrap_offset = video_vpts - * audio_pts + audio_wrap_offset = audio_vpts - * - * - video_wrap_offset should be equal to audio_wrap_offset as to have - * perfect audio and video sync. They will differ on brief periods due - * discontinuity correction. - * - metronom should also interpolate vpts values most of the time as - * video_pts and audio_vpts are not given for every frame. - * - corrections to the frame rate may be needed to cope with bad - * encoded streams. - */ - -#ifndef HAVE_METRONOM_H -#define HAVE_METRONOM_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef XINE_COMPILE -# include "video_out.h" -# include "xine.h" -#else -# include -# include -#endif - -typedef struct metronom_s metronom_t ; -typedef struct metronom_clock_s metronom_clock_t; -typedef struct scr_plugin_s scr_plugin_t; - -/* metronom prebuffer can be adjusted with XINE_PARAM_METRONOM_PREBUFFER. - * it sets how much the first video/audio frame should be delayed to - * have some prebuffering at the output layers. reducing this value (about - * 1/8 sec) may result in faster seeking (good to simulate play backwards, - * for example). - */ -#define PREBUFFER_PTS_OFFSET 12000 - - /* see below */ -#define DISC_STREAMSTART 0 -#define DISC_RELATIVE 1 -#define DISC_ABSOLUTE 2 -#define DISC_STREAMSEEK 3 - -struct metronom_s { - - /* - * called by audio output driver to inform metronom about current audio - * samplerate - * - * parameter pts_per_smpls : 1/90000 sec per 65536 samples - */ - void (*set_audio_rate) (metronom_t *self, int64_t pts_per_smpls); - - /* - * called by video output driver for *every* frame - * - * parameter frame containing pts, scr, ... information - * - * will set vpts field in frame - * - * this function will also update video_wrap_offset if a discontinuity - * is detected (read the comentaries below about discontinuities). - * - */ - - void (*got_video_frame) (metronom_t *self, vo_frame_t *frame); - - /* - * called by audio output driver whenever audio samples are delivered to it - * - * parameter pts : pts for audio data if known, 0 otherwise - * nsamples : number of samples delivered - * - * return value: virtual pts for audio data - * - * this function will also update audio_wrap_offset if a discontinuity - * is detected (read the comentaries below about discontinuities). - * - */ - - int64_t (*got_audio_samples) (metronom_t *self, int64_t pts, - int nsamples); - - /* - * called by SPU decoder whenever a packet is delivered to it - * - * parameter pts : pts for SPU packet if known, 0 otherwise - * - * return value: virtual pts for SPU packet - * (this is the only pts to vpts function that cannot update the wrap_offset - * due to the lack of regularity on spu packets) - */ - - int64_t (*got_spu_packet) (metronom_t *self, int64_t pts); - - /* - * tell metronom about discontinuities. - * - * these functions are called due to a discontinuity detected at - * demux stage. - * - * there are different types of discontinuities: - * - * DISC_STREAMSTART : new stream starts, expect pts values to start - * from zero immediately - * DISC_RELATIVE : typically a wrap-around, expect pts with - * a specified offset from the former ones soon - * DISC_ABSOLUTE : typically a new menu stream (nav packets) - * pts will start from given value soon - * DISC_STREAMSEEK : used by video and audio decoder loop, - * when a buffer with BUF_FLAG_SEEK set is encountered; - * applies the necessary vpts offset for the seek in - * metronom, but keeps the vpts difference between - * audio and video, so that metronom doesn't cough - */ - void (*handle_audio_discontinuity) (metronom_t *self, int type, int64_t disc_off); - void (*handle_video_discontinuity) (metronom_t *self, int type, int64_t disc_off); - - /* - * set/get options for metronom, constants see below - */ - void (*set_option) (metronom_t *self, int option, int64_t value); - int64_t (*get_option) (metronom_t *self, int option); - - /* - * set a master metronom - * this is currently useful to sync independently generated streams - * (e.g. by post plugins) to the discontinuity domain of another - * metronom - */ - void (*set_master) (metronom_t *self, metronom_t *master); - - void (*exit) (metronom_t *self); - -#ifdef METRONOM_INTERNAL - /* - * metronom internal stuff - */ - xine_t *xine; - - metronom_t *master; - - int64_t pts_per_smpls; - - int64_t video_vpts; - int64_t spu_vpts; - int64_t audio_vpts; - int64_t audio_vpts_rmndr; /* the remainder for integer division */ - - int64_t vpts_offset; - - int64_t video_drift; - int64_t video_drift_step; - - int audio_samples; - int64_t audio_drift_step; - - int64_t prebuffer; - int64_t av_offset; - int64_t spu_offset; - - pthread_mutex_t lock; - - int have_video; - int have_audio; - int video_discontinuity_count; - int audio_discontinuity_count; - int discontinuity_handled_count; - pthread_cond_t video_discontinuity_reached; - pthread_cond_t audio_discontinuity_reached; - - int force_video_jump; - int force_audio_jump; - - int64_t img_duration; - int img_cpt; - int64_t last_video_pts; - int64_t last_audio_pts; - - int video_mode; -#endif -}; - -/* - * metronom options - */ - -#define METRONOM_AV_OFFSET 2 -#define METRONOM_ADJ_VPTS_OFFSET 3 -#define METRONOM_FRAME_DURATION 4 -#define METRONOM_SPU_OFFSET 5 -#define METRONOM_VPTS_OFFSET 6 -#define METRONOM_PREBUFFER 7 - -metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_PROTECTED; - -/* FIXME: reorder this structure on the next cleanup to remove the dummies */ -struct metronom_clock_s { - - /* - * set/get options for clock, constants see below - */ - void (*set_option) (metronom_clock_t *self, int option, int64_t value); - int64_t (*get_option) (metronom_clock_t *self, int option); - - /* - * system clock reference (SCR) functions - */ - -#ifdef METRONOM_CLOCK_INTERNAL - /* - * start clock (no clock reset) - * at given pts - */ - void (*start_clock) (metronom_clock_t *self, int64_t pts); - - - /* - * stop metronom clock - */ - void (*stop_clock) (metronom_clock_t *self); - - - /* - * resume clock from where it was stopped - */ - void (*resume_clock) (metronom_clock_t *self); -#else - void *dummy1; - void *dummy2; - void *dummy3; -#endif - - - /* - * get current clock value in vpts - */ - int64_t (*get_current_time) (metronom_clock_t *self); - - - /* - * adjust master clock to external timer (e.g. audio hardware) - */ - void (*adjust_clock) (metronom_clock_t *self, int64_t desired_pts); - -#ifdef METRONOM_CLOCK_INTERNAL - /* - * set clock speed - * for constants see xine_internal.h - */ - - int (*set_fine_speed) (metronom_clock_t *self, int speed); -#else - void *dummy4; -#endif - - /* - * (un)register a System Clock Reference provider at the metronom - */ - int (*register_scr) (metronom_clock_t *self, scr_plugin_t *scr); - void (*unregister_scr) (metronom_clock_t *self, scr_plugin_t *scr); - -#ifdef METRONOM_CLOCK_INTERNAL - void (*exit) (metronom_clock_t *self); - - xine_t *xine; - - scr_plugin_t *scr_master; - scr_plugin_t **scr_list; - pthread_t sync_thread; - int thread_running; - int scr_adjustable; -#else - void *dummy5; - void *dummy6; - void *dummy7; - void *dummy8; - pthread_t dummy9; - int dummy10; - int dummy11; -#endif - - int speed; - -#ifdef METRONOM_CLOCK_INTERNAL - pthread_mutex_t lock; - pthread_cond_t cancel; -#endif -}; - -metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_PROTECTED; - -/* - * clock options - */ - -#define CLOCK_SCR_ADJUSTABLE 1 - -/* - * SCR (system clock reference) plugins - */ - -struct scr_plugin_s -{ - int (*get_priority) (scr_plugin_t *self); - - /* - * set/get clock speed - * - * for speed constants see xine_internal.h - * returns actual speed - */ - - int (*set_fine_speed) (scr_plugin_t *self, int speed); - - void (*adjust) (scr_plugin_t *self, int64_t vpts); - - void (*start) (scr_plugin_t *self, int64_t start_vpts); - - int64_t (*get_current) (scr_plugin_t *self); - - void (*exit) (scr_plugin_t *self); - - metronom_clock_t *clock; - - int interface_version; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h deleted file mode 100644 index 7b04c0a17..000000000 --- a/src/xine-engine/osd.h +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * OSD stuff (text and graphic primitives) - */ - -#ifndef HAVE_OSD_H -#define HAVE_OSD_H - -#ifdef HAVE_ICONV -# include -#endif - -#ifdef XINE_COMPILE -# include "video_overlay.h" -# ifdef __OSD_C__ -# include "alphablend.h" -# endif -#else -# include -#endif - -typedef struct osd_object_s osd_object_t; -typedef struct osd_renderer_s osd_renderer_t; -typedef struct osd_font_s osd_font_t; -typedef struct osd_ft2context_s osd_ft2context_t; - -struct osd_object_s { - osd_object_t *next; - osd_renderer_t *renderer; - - int width, height; /* work area dimentions */ - uint8_t *area; /* work area */ - int display_x,display_y; /* where to display it in screen */ - - /* clipping box inside work area */ - int x1, y1; - int x2, y2; - - uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ - uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ - -#ifdef HAVE_ICONV - iconv_t cd; /* iconv handle of encoding */ - char *encoding; /* name of encoding */ -#endif - - osd_font_t *font; - osd_ft2context_t *ft2; - - int32_t handle; -}; - -/* this one is public */ -struct xine_osd_s { - osd_object_t osd; -}; - -struct osd_renderer_s { - - xine_stream_t *stream; - - /* - * open a new osd object. this will allocated an empty (all zero) drawing - * area where graphic primitives may be used. - * It is ok to specify big width and height values. The render will keep - * track of the smallest changed area to not generate too big overlays. - * A default palette is initialized (i sugest keeping color 0 as transparent - * for the sake of simplicity) - */ - osd_object_t* (*new_object) (osd_renderer_t *this, int width, int height); - - /* - * free osd object - */ - void (*free_object) (osd_object_t *osd_to_close); - - - /* - * send the osd to be displayed at given pts (0=now) - * the object is not changed. there may be subsequent drawing on it. - */ - int (*show) (osd_object_t *osd, int64_t vpts ); - - /* - * send event to hide osd at given pts (0=now) - * the object is not changed. there may be subsequent drawing on it. - */ - int (*hide) (osd_object_t *osd, int64_t vpts ); - - /* - * draw point. - */ - void (*point) (osd_object_t *osd, int x, int y, int color); - - /* - * Bresenham line implementation on osd object - */ - void (*line) (osd_object_t *osd, - int x1, int y1, int x2, int y2, int color ); - - /* - * filled rectangle - */ - void (*filled_rect) (osd_object_t *osd, - int x1, int y1, int x2, int y2, int color ); - - /* - * set palette (color and transparency) - */ - void (*set_palette) (osd_object_t *osd, const uint32_t *color, const uint8_t *trans ); - - /* - * set on existing text palette - * (-1 to set used specified palette) - * - * color_base specifies the first color index to use for this text - * palette. The OSD palette is then modified starting at this - * color index, up to the size of the text palette. - * - * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. - */ - void (*set_text_palette) (osd_object_t *osd, int palette_number, - int color_base ); - - /* - * get palette (color and transparency) - */ - void (*get_palette) (osd_object_t *osd, uint32_t *color, - uint8_t *trans); - - /* - * set position were overlay will be blended - */ - void (*set_position) (osd_object_t *osd, int x, int y); - - /* - * set the font of osd object - */ - - int (*set_font) (osd_object_t *osd, const char *fontname, int size); - - /* - * set encoding of text - * - * NULL ... no conversion (iso-8859-1) - * "" ... locale encoding - */ - int (*set_encoding) (osd_object_t *osd, const char *encoding); - - /* - * render text in current encoding on x,y position - * no \n yet - * - * The text is assigned the colors starting at the index specified by - * color_base up to the size of the text palette. - * - * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. - */ - int (*render_text) (osd_object_t *osd, int x1, int y1, - const char *text, int color_base); - - /* - * get width and height of how text will be renderized - */ - int (*get_text_size) (osd_object_t *osd, const char *text, - int *width, int *height); - - /* - * close osd rendering engine - * loaded fonts are unloaded - * osd objects are closed - */ - void (*close) (osd_renderer_t *this); - - /* - * clear an osd object (empty drawing area) - */ - void (*clear) (osd_object_t *osd ); - - /* - * paste a bitmap with optional palette mapping - */ - void (*draw_bitmap) (osd_object_t *osd, uint8_t *bitmap, - int x1, int y1, int width, int height, - uint8_t *palette_map); - - /* - * send the osd to be displayed (unscaled) at given pts (0=now) - * the object is not changed. there may be subsequent drawing on it. - * overlay is blended at output (screen) resolution. - */ - int (*show_unscaled) (osd_object_t *osd, int64_t vpts ); - - /* - * see xine.h for defined XINE_OSD_CAP_ values. - */ - uint32_t (*get_capabilities) (osd_object_t *osd); - - /* private stuff */ - - pthread_mutex_t osd_mutex; - video_overlay_event_t event; - osd_object_t *osds; /* instances of osd */ - osd_font_t *fonts; /* loaded fonts */ - int textpalette; /* default textpalette */ - -}; - -/* - * initialize the osd rendering engine - */ -osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ); - - -/* - * The size of a text palette - */ - -#define TEXT_PALETTE_SIZE 11 - -/* - * Preassigned color indices for rendering text - * (more can be added, not exceeding OVL_PALETTE_SIZE) - */ - -#define OSD_TEXT1 (0 * TEXT_PALETTE_SIZE) -#define OSD_TEXT2 (1 * TEXT_PALETTE_SIZE) -#define OSD_TEXT3 (2 * TEXT_PALETTE_SIZE) -#define OSD_TEXT4 (3 * TEXT_PALETTE_SIZE) -#define OSD_TEXT5 (4 * TEXT_PALETTE_SIZE) -#define OSD_TEXT6 (5 * TEXT_PALETTE_SIZE) -#define OSD_TEXT7 (6 * TEXT_PALETTE_SIZE) -#define OSD_TEXT8 (7 * TEXT_PALETTE_SIZE) -#define OSD_TEXT9 (8 * TEXT_PALETTE_SIZE) -#define OSD_TEXT10 (9 * TEXT_PALETTE_SIZE) - -/* - * Defined palettes for rendering osd text - * (more can be added later) - */ - -#define NUMBER_OF_TEXT_PALETTES 4 -#define TEXTPALETTE_WHITE_BLACK_TRANSPARENT 0 -#define TEXTPALETTE_WHITE_NONE_TRANSPARENT 1 -#define TEXTPALETTE_WHITE_NONE_TRANSLUCID 2 -#define TEXTPALETTE_YELLOW_BLACK_TRANSPARENT 3 - -#ifdef __OSD_C__ - -/* This text descriptions are used for config screen */ -static const char *textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { - "white-black-transparent", - "white-none-transparent", - "white-none-translucid", - "yellow-black-transparent", - NULL}; - - -/* - Palette entries as used by osd fonts: - - 0: not used by font, always transparent - 1: font background, usually transparent, may be used to implement - translucid boxes where the font will be printed. - 2-5: transition between background and border (usually only alpha - value changes). - 6: font border. if the font is to be displayed without border this - will probably be adjusted to font background or near. - 7-9: transition between border and foreground - 10: font color (foreground) -*/ - -/* - The palettes below were made by hand, ie, i just throw - values that seemed to do the transitions i wanted. - This can surelly be improved a lot. [Miguel] -*/ - -static const clut_t textpalettes_color[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { -/* white, black border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0x40, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* white, no border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* white, no border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0xa0, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xe0, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* yellow, black border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0x40, 0x84, 0x60), /*7*/ - CLUT_Y_CR_CB_INIT(0x70, 0x88, 0x40), /*8*/ - CLUT_Y_CR_CB_INIT(0xb0, 0x8a, 0x20), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00), /*10*/ - }, -}; - -static const uint8_t textpalettes_trans[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { - {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, - {0, 0, 0, 0, 0, 0, 2, 6, 9, 12, 15 }, - {0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }, - {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, -}; - -#endif /* __OSD_C__ */ - -#endif - diff --git a/src/xine-engine/plugin_catalog.h b/src/xine-engine/plugin_catalog.h deleted file mode 100644 index fd9afb959..000000000 --- a/src/xine-engine/plugin_catalog.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine-internal header: Definitions for plugin lists - */ - -#ifndef _PLUGIN_CATALOG_H -#define _PLUGIN_CATALOG_H - -#ifdef XINE_COMPILE -# include "xine_plugin.h" -# include "xineutils.h" -#else -# include -# include -#endif - -#define DECODER_MAX 128 -#define PLUGIN_MAX 256 - -/* the engine takes this many plugins for one stream type */ -#define PLUGINS_PER_TYPE 10 - -typedef struct { - char *filename; - off_t filesize; - time_t filemtime; - void *lib_handle; - int ref; /* count number of classes */ - int no_unload; /* set if the file can't be unloaded */ -} plugin_file_t ; - -typedef struct { - plugin_file_t *file; - plugin_info_t *info; - void *plugin_class; - int ref; /* count intances of plugins */ - int priority; -} plugin_node_t ; - -struct plugin_catalog_s { - xine_sarray_t *plugin_lists[PLUGIN_TYPE_MAX]; - - xine_sarray_t *cache_list; - xine_list_t *file_list; - - plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; - plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; - plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; - - const char *ids[PLUGIN_MAX]; - - /* memory block for the decoder priority config entry descriptions */ - char *prio_desc[DECODER_MAX]; - - pthread_mutex_t lock; - - int plugin_count; - int decoder_count; -}; -typedef struct plugin_catalog_s plugin_catalog_t; - -/* - * load plugins into catalog - * - * all input+demux plugins will be fully loaded+initialized - * decoder plugins are loaded on demand - * video/audio output plugins have special load/probe functions - */ -void _x_scan_plugins (xine_t *this) XINE_PROTECTED; - - -/* - * dispose all currently loaded plugins (shutdown) - */ - -void _x_dispose_plugins (xine_t *this) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/post.h b/src/xine-engine/post.h deleted file mode 100644 index 1995ca82f..000000000 --- a/src/xine-engine/post.h +++ /dev/null @@ -1,405 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * post plugin definitions - */ - -#ifndef XINE_POST_H -#define XINE_POST_H - -#ifdef XINE_COMPILE -# include "xine.h" -# include "video_out.h" -# include "audio_out.h" -# include "xine_internal.h" -# include "xineutils.h" -#else -# include -# include -# include -# include -# include -#endif - -#define POST_PLUGIN_IFACE_VERSION 9 - - -typedef struct post_class_s post_class_t; -typedef struct post_plugin_s post_plugin_t; -typedef struct post_in_s post_in_t; -typedef struct post_out_s post_out_t; - -struct post_class_s { - - /* - * open a new instance of this plugin class - */ - post_plugin_t* (*open_plugin) (post_class_t *this, int inputs, - xine_audio_port_t **audio_target, - xine_video_port_t **video_target); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * free all class-related resources - */ - - void (*dispose) (post_class_t *this); -}; - -#define default_post_class_dispose (void (*) (post_class_t *this))free - -struct post_plugin_s { - - /* public part of the plugin */ - xine_post_t xine_post; - - /* - * the connections announced by the plugin - * the plugin must fill these with xine_post_{in,out}_t on init - */ - xine_list_t *input; - xine_list_t *output; - - /* - * close down, free all resources - */ - void (*dispose) (post_plugin_t *this); - - /* plugins don't have to init the stuff below */ - - /* - * the running ticket - * - * the plugin must assure to check for ticket revocation in - * intervals of finite length; this means that you must release - * the ticket before any operation that might block; - * note that all port functions are safe in this respect - * - * the running ticket is assigned to you by the engine - */ - xine_ticket_t *running_ticket; - - /* this is needed by the engine to decrement the reference counter - * on disposal of the plugin, but since this is useful, we expose it */ - xine_t *xine; - - /* used when the user requests a list of all inputs/outputs */ - const char **input_ids; - const char **output_ids; - - /* used by plugin loader */ - void *node; - - /* has dispose been called */ - int dispose_pending; -}; - -/* helper function to initialize a post_plugin_t */ -void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) XINE_PROTECTED; - -struct post_in_s { - - /* public part of the input */ - xine_post_in_t xine_in; - - /* backward reference so that you have access to the post plugin */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; -}; - -struct post_out_s { - - /* public part of the output */ - xine_post_out_t xine_out; - - /* backward reference so that you have access to the post plugin */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; -}; - - -/* Post plugins work by intercepting calls to video or audio ports - * in the sense of the decorator design pattern. They reuse the - * functions of a given target port, but add own functionality in - * front of that port by creating a new port structure and filling in - * the function pointers with pointers to own functions that - * would do something and then call the original port function. - * - * Much the same is done with video frames which have their own - * set of functions attached that you might need to decorate. - */ - - -/* helper structure for intercepting video port calls */ -typedef struct post_video_port_s post_video_port_t; -struct post_video_port_s { - - /* the new public port with replaced function pointers */ - xine_video_port_t new_port; - - /* the original port to call its functions from inside yours */ - xine_video_port_t *original_port; - - /* if you want to decide yourself, whether a given frame should - * be intercepted, fill in this function; get_frame() acts as - * a template method and asks your function; return a boolean; - * the default is to intercept all frames */ - int (*intercept_frame)(post_video_port_t *self, vo_frame_t *frame); - - /* the new frame function pointers */ - vo_frame_t *new_frame; - - /* if you want to decide yourself, whether the preprocessing functions - * should still be routed when draw is intercepted, fill in this - * function; _x_post_intercept_video_frame() acts as a template method - * and asks your function; return a boolean; the default is _not_ to - * route preprocessing functions when draw is intercepted */ - int (*route_preprocessing_procs)(post_video_port_t *self, vo_frame_t *frame); - - /* if you want to decide yourself, whether the overlay manager should - * be intercepted, fill in this function; get_overlay_manager() acts as - * a template method and asks your function; return a boolean; - * the default is _not_ to intercept the overlay manager */ - int (*intercept_ovl)(post_video_port_t *self); - - /* the new public overlay manager with replaced function pointers */ - video_overlay_manager_t *new_manager; - - /* the original manager to call its functions from inside yours */ - video_overlay_manager_t *original_manager; - - /* usage counter: how many objects are floating around that need - * these pointers to exist */ - int usage_count; - pthread_mutex_t usage_lock; - - /* the stream we are being fed by; NULL means no stream is connected; - * this may be an anonymous stream */ - xine_stream_t *stream; - - /* point to a mutex here, if you need some synchronization */ - pthread_mutex_t *port_lock; - pthread_mutex_t *frame_lock; - pthread_mutex_t *manager_lock; - - /* backward reference so that you have access to the post plugin - * when the call only gives you the port */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; - -#ifdef POST_INTERNAL - /* some of the above members are to be directly included here, but - * adding the structures would mean that post_video_port_t becomes - * depended of the sizes of these structs; solution: we add pointers - * above and have them point into the memory provided here; - * note that the overlay manager needs to be first so that we can - * reconstruct the post_video_port_t* from overlay manager calls */ - - /* any change here requires a change in _x_post_ovl_manager_to_port() - * below! */ - - video_overlay_manager_t manager_storage; - vo_frame_t frame_storage; - - /* this is used to keep a linked list of free vo_frame_t's */ - vo_frame_t *free_frame_slots; - pthread_mutex_t free_frames_lock; -#endif -}; - -/* use this to create a new decorated video port in which - * port functions will be replaced with own implementations; - * for convenience, this can also create a related post_in_t and post_out_t */ -post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *port, - post_in_t **input, post_out_t **output) XINE_PROTECTED; - -/* use this to decorate and to undecorate a frame so that its functions - * can be replaced with own implementations, decoration is usually done in - * get_frame(), undecoration in frame->free() */ -vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) XINE_PROTECTED; -vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port) XINE_PROTECTED; - -/* when you want to pass a frame call on to the original issuer of the frame, - * you need to propagate potential changes up and down the pipe, so the usual - * procedure for this situation would be: - * - * _x_post_frame_copy_down(frame, frame->next); - * frame->next->function(frame->next); - * _x_post_frame_copy_up(frame, frame->next); - */ -void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) XINE_PROTECTED; -void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) XINE_PROTECTED; - -/* when you shortcut a frames usual draw() travel so that it will never reach - * the draw() function of the original issuer, you still have to do some - * housekeeping on the frame, before returning control up the pipe */ -void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) XINE_PROTECTED; - -/* use this to create a new, trivially decorated overlay manager in which - * port functions can be replaced with own implementations */ -void _x_post_intercept_overlay_manager(video_overlay_manager_t *manager, post_video_port_t *port) XINE_PROTECTED; - -/* pointer retrieval functions */ -static inline post_video_port_t *_x_post_video_frame_to_port(vo_frame_t *frame) { - return (post_video_port_t *)frame->port; -} - -static inline post_video_port_t *_x_post_ovl_manager_to_port(video_overlay_manager_t *manager) { -#ifdef POST_INTERNAL - return (post_video_port_t *)( (uint8_t *)manager - - (unsigned)&(((post_video_port_t *)NULL)->manager_storage) ); -#else - return (post_video_port_t *)( (uint8_t *)manager - sizeof(post_video_port_t) ); -#endif -} - - -/* helper structure for intercepting audio port calls */ -typedef struct post_audio_port_s post_audio_port_t; -struct post_audio_port_s { - - /* the new public port with replaced function pointers */ - xine_audio_port_t new_port; - - /* the original port to call its functions from inside yours */ - xine_audio_port_t *original_port; - - /* the stream we are being fed by; NULL means no stream is connected; - * this may be an anonymous stream */ - xine_stream_t *stream; - - pthread_mutex_t usage_lock; - /* usage counter: how many objects are floating around that need - * these pointers to exist */ - int usage_count; - - /* some values remembered by (port->open) () */ - uint32_t bits; - uint32_t rate; - uint32_t mode; - - /* point to a mutex here, if you need some synchronization */ - pthread_mutex_t *port_lock; - - /* backward reference so that you have access to the post plugin - * when the call only gives you the port */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; -}; - -/* use this to create a new decorated audio port in which - * port functions will be replaced with own implementations */ -post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *port, - post_in_t **input, post_out_t **output) XINE_PROTECTED; - - -/* this will allow pending rewire operations, calling this at the beginning - * of decoder-called functions like get_buffer() and open() is a good idea - * (if you do not intercept get_buffer() or open(), this will be done automatically) */ -static inline void _x_post_rewire(post_plugin_t *post) { - if (post->running_ticket->ticket_revoked) - post->running_ticket->renew(post->running_ticket, 1); -} - -/* with these functions you can switch interruptions like rewiring or engine pausing - * off for a block of code; use this only when really necessary */ -static inline void _x_post_lock(post_plugin_t *post) { - post->running_ticket->acquire(post->running_ticket, 1); -} -static inline void _x_post_unlock(post_plugin_t *post) { - post->running_ticket->release(post->running_ticket, 1); - _x_post_rewire(post); -} - -/* the standard disposal operation; returns 1 if the plugin is really - * disposed and you should free everything you malloc()ed yourself */ -int _x_post_dispose(post_plugin_t *post) XINE_PROTECTED; - - -/* macros to handle usage counter */ - -/* WARNING! - * note that _x_post_dec_usage() can call dispose, so be sure to - * not use any potentially already freed memory after this */ - -#define _x_post_inc_usage(port) \ -do { \ - pthread_mutex_lock(&(port)->usage_lock); \ - (port)->usage_count++; \ - pthread_mutex_unlock(&(port)->usage_lock); \ -} while(0) - -#define _x_post_dec_usage(port) \ -do { \ - pthread_mutex_lock(&(port)->usage_lock); \ - (port)->usage_count--; \ - if ((port)->usage_count == 0) { \ - if ((port)->post->dispose_pending) { \ - pthread_mutex_unlock(&(port)->usage_lock); \ - (port)->post->dispose((port)->post); \ - } else \ - pthread_mutex_unlock(&(port)->usage_lock); \ - } else \ - pthread_mutex_unlock(&(port)->usage_lock); \ -} while(0) - - -/* macros to create parameter descriptors */ - -#define START_PARAM_DESCR( param_t ) \ -static param_t temp_s; \ -static xine_post_api_parameter_t temp_p[] = { - -#define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \ -{ param_type, #var, sizeof(temp_s.var), \ - (char*)&temp_s.var-(char*)&temp_s, enumv, min, max, readonly, descr }, - -#define END_PARAM_DESCR( name ) \ - { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \ -}; \ -static xine_post_api_descr_t name = { \ - sizeof( temp_s ), \ - temp_p \ -}; - -#endif diff --git a/src/xine-engine/refcounter.h b/src/xine-engine/refcounter.h deleted file mode 100644 index a662a974e..000000000 --- a/src/xine-engine/refcounter.h +++ /dev/null @@ -1,46 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ -#ifndef HAVE_REFCOUNTER_H -#define HAVE_REFCOUNTER_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -typedef struct { - pthread_mutex_t lock; - void* object; /* referenced object */ - void (*destructor)(void *); /* object destructor */ - int count; -} refcounter_t; - -typedef void (*refcounter_destructor)(void*); - -refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_PROTECTED; - -int _x_refcounter_inc(refcounter_t *refcounter) XINE_PROTECTED; - -int _x_refcounter_dec(refcounter_t *refcounter) XINE_PROTECTED; - -void _x_refcounter_dispose(refcounter_t *refcounter) XINE_PROTECTED; - -#endif /* HAVE_REFCOUNTER_H */ diff --git a/src/xine-engine/resample.h b/src/xine-engine/resample.h deleted file mode 100644 index 40b4de486..000000000 --- a/src/xine-engine/resample.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * utilitiy functions for audio drivers - * - * FIXME: not all of them are implemented yet - */ - -#ifndef HAVE_RESAMPLE_H -#define HAVE_RESAMPLE_H - -#define RESAMPLE_MAX_CHANNELS 6 - -void _x_audio_out_resample_stereo(int16_t* last_sample, - int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_mono(int16_t* last_sample, - int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_4channel(int16_t* last_sample, - int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_5channel(int16_t* last_sample, - int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_6channel(int16_t* last_sample, - int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_8to16(int8_t* input_samples, - int16_t* output_samples, uint32_t samples) XINE_PROTECTED; - -void _x_audio_out_resample_16to8(int16_t* input_samples, - int8_t* output_samples, uint32_t samples) XINE_PROTECTED; - -void _x_audio_out_resample_monotostereo(int16_t* input_samples, - int16_t* output_samples, uint32_t frames) XINE_PROTECTED; - -void _x_audio_out_resample_stereotomono(int16_t* input_samples, - int16_t* output_samples, uint32_t frames) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/scratch.h b/src/xine-engine/scratch.h deleted file mode 100644 index c0e591d31..000000000 --- a/src/xine-engine/scratch.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * scratch buffer for log output - */ - -#ifndef HAVE_SCRATCH_H -#define HAVE_SCRATCH_H - -#include -#include - -typedef struct scratch_buffer_s scratch_buffer_t; - -#define SCRATCH_LINE_LEN_MAX 1024 - -struct scratch_buffer_s { - - void -#if __GNUC__ >= 3 - __attribute__((__format__(__printf__, 2, 0))) -#endif - (*scratch_printf) (scratch_buffer_t *this, const char *format, va_list ap); - - char **(*get_content) (scratch_buffer_t *this); - - void (*dispose) (scratch_buffer_t *this); - - char **lines; - char **ordered; - - int num_lines; - int cur; - - pthread_mutex_t lock; -}; - -scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/spu.h b/src/xine-engine/spu.h deleted file mode 100644 index daba7866b..000000000 --- a/src/xine-engine/spu.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2007 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef XINE_UTILS_SPU_H -#define XINE_UTILS_SPU_H - -#ifndef XINE_PROTECTED -#define XINE_PROTECTED -#endif - -typedef struct xine_spu_opacity_s xine_spu_opacity_t; - -struct xine_spu_opacity_s { - uint8_t black, colour; -}; - -void _x_spu_misc_init (xine_t *); - -void _x_spu_get_opacity (xine_t *, xine_spu_opacity_t *) XINE_PROTECTED; - -/* in: trans = 0..255, 0=opaque - * out: 0..255, 0=transparent - */ -int _x_spu_calculate_opacity (const clut_t *, uint8_t trans, const xine_spu_opacity_t *) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/spu_decoder.h b/src/xine-engine/spu_decoder.h deleted file mode 100644 index dcf9107f7..000000000 --- a/src/xine-engine/spu_decoder.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * spu_decoder_api.h - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * This file is part of xine, a unix 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, - * - */ - -#ifndef HAVE_SPU_API_H -#define HAVE_SPU_API_H - -#ifdef XINE_COMPILE -# include -# include "buffer.h" -#else -# include -# include -#endif - -#define SPU_DECODER_IFACE_VERSION 17 - -/* - * generic xine spu decoder plugin interface - */ - -typedef struct spu_decoder_class_s spu_decoder_class_t; -typedef struct spu_decoder_s spu_decoder_t; - -struct spu_decoder_class_s { - - /* - * open a new instance of this plugin class - */ - spu_decoder_t* (*open_plugin) (spu_decoder_class_t *this, xine_stream_t *stream); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * free all class-related resources - */ - void (*dispose) (spu_decoder_class_t *this); -}; - -#define default_spu_decoder_class_dispose (void (*) (spu_decoder_class_t *this))free - -struct spu_decoder_s { - - /* - * decode data from buf and feed the overlay to overlay manager - */ - void (*decode_data) (spu_decoder_t *this, buf_element_t *buf); - - /* - * reset decoder after engine flush (prepare for new - * SPU data not related to recently decoded data) - */ - void (*reset) (spu_decoder_t *this); - - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - void (*discontinuity) (spu_decoder_t *this); - - /* - * close down, free all resources - */ - void (*dispose) (spu_decoder_t *this); - - /* - * When the SPU decoder also handles data used in user interaction, - * you can query the related information here. The typical example - * for this is DVD NAV packets which are handled by the SPU decoder - * and can be received readily parsed from here. - * The caller and the decoder must agree on the structure which is - * passed here. - * This function pointer may be NULL, if the plugin does not have - * such functionality. - */ - int (*get_interact_info) (spu_decoder_t *this, void *data); - - /* - * When the SPU decoder also handles menu overlays for user inter- - * action, you can set a menu button here. The typical example for - * this is DVD menus. - * This function pointer may be NULL, if the plugin does not have - * such functionality. - */ - void (*set_button) (spu_decoder_t *this_gen, int32_t button, int32_t mode); - - void *node; /* used by plugin loader */ -}; - - -/* SPU decoders differ from video and audio decoders in one significant - * way: unlike audio and video, SPU streams are not continuous; - * this results in another difference, programmers have to consider: - * while both audio and video decoders are automatically blocked in - * their get_buffer()/get_frame() methods when the output cannot take - * any more data, this does not work for SPU, because it could take - * minutes before the next free slot becomes available and we must not - * block the decoder thread for that long; - * therefore, we provide a convenience function for SPU decoders which - * implements a wait until a timestamp sufficiently close to the VPTS - * of the next SPU is reached, but the waiting will end before that, - * if some outside condition requires us to release the decoder thread - * to other tasks; - * if this functions returns with 1, noone needs the decoder thread and - * you may continue waiting; if it returns 0, finish whatever you are - * doing and return; - * the usual pattern for SPU decoders is this: - * - * do { - * spu = prepare_spu(); - * int thread_vacant = _x_spu_decoder_sleep(this->stream, spu->vpts); - * int success = process_spu(spu); - * } while (!success && thread_vacant); - */ -int _x_spu_decoder_sleep(xine_stream_t *, int64_t next_spu_vpts) XINE_PROTECTED; - -#endif /* HAVE_SPUDEC_H */ diff --git a/src/xine-engine/video_decoder.h b/src/xine-engine/video_decoder.h deleted file mode 100644 index 705efa3da..000000000 --- a/src/xine-engine/video_decoder.h +++ /dev/null @@ -1,111 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine video decoder plugin interface - */ - -#ifndef HAVE_VIDEO_DECODER_H -#define HAVE_VIDEO_DECODER_H - -#ifdef XINE_COMPILE -# include -# include "buffer.h" -#else -# include -# include -#endif - -#define VIDEO_DECODER_IFACE_VERSION 19 - - -/* - * generic xine video decoder plugin interface - */ - -typedef struct video_decoder_class_s video_decoder_class_t; -typedef struct video_decoder_s video_decoder_t; - -struct video_decoder_class_s { - - /* - * open a new instance of this plugin class - */ - video_decoder_t* (*open_plugin) (video_decoder_class_t *this, xine_stream_t *stream); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * free all class-related resources - */ - void (*dispose) (video_decoder_class_t *this); -}; - -#define default_video_decoder_class_dispose (void (*) (video_decoder_class_t *this))free - -struct video_decoder_s { - - /* - * decode data from buf and feed decoded frames to - * video output - */ - void (*decode_data) (video_decoder_t *this, buf_element_t *buf); - - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - void (*reset) (video_decoder_t *this); - - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - void (*discontinuity) (video_decoder_t *this); - - /* - * flush out any frames that are still stored in the decoder - */ - void (*flush) (video_decoder_t *this); - - /* - * close down, free all resources - */ - void (*dispose) (video_decoder_t *this); - - - void *node; /*used by plugin loader */ - -}; - -#endif diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h deleted file mode 100644 index 8efdae9f6..000000000 --- a/src/xine-engine/video_out.h +++ /dev/null @@ -1,466 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * - * xine version of video_out.h - * - * vo_frame : frame containing yuv data and timing info, - * transferred between video_decoder and video_output - * - * vo_driver : lowlevel, platform-specific video output code - * - * vo_port : generic frame_handling code, uses - * a vo_driver for output - */ - -#ifndef HAVE_VIDEO_OUT_H -#define HAVE_VIDEO_OUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#ifdef XINE_COMPILE -# include "xine.h" -# include "buffer.h" -#else -# include -# include -#endif - - -typedef struct vo_frame_s vo_frame_t; -typedef struct vo_driver_s vo_driver_t; -typedef struct video_driver_class_s video_driver_class_t; -typedef struct vo_overlay_s vo_overlay_t; -typedef struct video_overlay_manager_s video_overlay_manager_t; - -/* public part, video drivers may add private fields - * - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ -struct vo_frame_s { - /* - * member functions - */ - - /* Duplicate picture data and acceleration specific data of a frame. */ - /* if the image format isn't already known by Xine. Currently this is needed */ - /* For all image formats except XINE_IMGFMT_YV12 and XINE_IMGFMT_YUY2 */ - void (*proc_duplicate_frame_data) (vo_frame_t *vo_img, vo_frame_t *src); - - /* tell video driver to copy/convert the whole of this frame, may be NULL */ - /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */ - void (*proc_frame) (vo_frame_t *vo_img); - - /* tell video driver to copy/convert a slice of this frame, may be NULL */ - /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */ - void (*proc_slice) (vo_frame_t *vo_img, uint8_t **src); - - /* tell video driver that the decoder starts a new field */ - void (*field) (vo_frame_t *vo_img, int which_field); - - /* append this frame to the display queue, - returns number of frames to skip if decoder is late */ - /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */ - int (*draw) (vo_frame_t *vo_img, xine_stream_t *stream); - - /* lock frame as reference, must be paired with free. - * most decoders/drivers do not need to call this function since - * newly allocated frames are already locked once. - */ - void (*lock) (vo_frame_t *vo_img); - - /* this frame is no longer used by the decoder, video driver, etc */ - void (*free) (vo_frame_t *vo_img); - - /* free memory/resources for this frame */ - void (*dispose) (vo_frame_t *vo_img); - - /* - * public variables to decoders and vo drivers - * changing anything here will require recompiling them both - */ - int64_t pts; /* presentation time stamp (1/90000 sec) */ - int64_t vpts; /* virtual pts, generated by metronom */ - int bad_frame; /* e.g. frame skipped or based on skipped frame */ - int duration; /* frame length in time, in 1/90000 sec */ - - /* yv12 (planar) base[0]: y, base[1]: u, base[2]: v */ - /* yuy2 (interleaved) base[0]: yuyv..., base[1]: --, base[2]: -- */ - uint8_t *base[3]; - int pitches[3]; - - /* info that can be used for interlaced output (e.g. tv-out) */ - int top_field_first; - int repeat_first_field; - /* note: progressive_frame is set wrong on many mpeg2 streams. for - * that reason, this flag should be interpreted as a "hint". - */ - int progressive_frame; - int picture_coding_type; - - /* cropping to be done */ - int crop_left, crop_right, crop_top, crop_bottom; - - int lock_counter; - pthread_mutex_t mutex; /* protect access to lock_count */ - - /* extra info coming from input or demuxers */ - extra_info_t *extra_info; - - /* additional information to be able to duplicate frames: */ - int width, height; - double ratio; /* aspect ratio */ - int format; /* IMGFMT_YV12 or IMGFMT_YUY2 */ - - int drawn; /* used by decoder, frame has already been drawn */ - int flags; /* remember the frame flags */ - int proc_called; /* track use of proc_*() methods */ - - /* Used to carry private data for accelerated plugins.*/ - void *accel_data; - - /* "backward" references to where this frame originates from */ - xine_video_port_t *port; - vo_driver_t *driver; - xine_stream_t *stream; - - /* displacement for overlays */ - int overlay_offset_x, overlay_offset_y; - - /* - * that part is used only by video_out.c for frame management - * obs: changing anything here will require recompiling vo drivers - */ - struct vo_frame_s *next; - - int id; /* debugging - track this frame */ - int is_first; -}; - - -/* - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ -struct xine_video_port_s { - - uint32_t (*get_capabilities) (xine_video_port_t *self); /* for constants see below */ - - /* open display driver for video output */ - /* when you are not a full-blown stream, but still need to open the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - void (*open) (xine_video_port_t *self, xine_stream_t *stream); - - /* - * get_frame - allocate an image buffer from display driver - * - * params : width == width of video to display. - * height == height of video to display. - * ratio == aspect ration information - * format == FOURCC descriptor of image format - * flags == field/prediction flags - */ - vo_frame_t* (*get_frame) (xine_video_port_t *self, uint32_t width, - uint32_t height, double ratio, - int format, int flags); - - /* retrieves the last displayed frame (useful for taking snapshots) */ - vo_frame_t* (*get_last_frame) (xine_video_port_t *self); - - /* overlay stuff */ - void (*enable_ovl) (xine_video_port_t *self, int ovl_enable); - - /* get overlay manager */ - video_overlay_manager_t* (*get_overlay_manager) (xine_video_port_t *self); - - /* flush video_out fifo */ - void (*flush) (xine_video_port_t *self); - - /* trigger immediate drawing */ - void (*trigger_drawing) (xine_video_port_t *self); - - /* Get/Set video property - * - * See VO_PROP_* bellow - */ - int (*get_property) (xine_video_port_t *self, int property); - int (*set_property) (xine_video_port_t *self, int property, int value); - - /* return true if port is opened for this stream, stream can be anonymous */ - int (*status) (xine_video_port_t *self, xine_stream_t *stream, - int *width, int *height, int64_t *img_duration); - - /* video driver is no longer used by decoder => close */ - /* when you are not a full-blown stream, but still need to close the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - void (*close) (xine_video_port_t *self, xine_stream_t *stream); - - /* called on xine exit */ - void (*exit) (xine_video_port_t *self); - - /* the driver in use */ - vo_driver_t *driver; - -}; - -/* constants for the get/set property functions */ -#define VO_PROP_INTERLACED 0 -#define VO_PROP_ASPECT_RATIO 1 -#define VO_PROP_HUE 2 -#define VO_PROP_SATURATION 3 -#define VO_PROP_CONTRAST 4 -#define VO_PROP_BRIGHTNESS 5 -#define VO_PROP_COLORKEY 6 -#define VO_PROP_AUTOPAINT_COLORKEY 7 -#define VO_PROP_ZOOM_X 8 -#define VO_PROP_PAN_SCAN 9 -#define VO_PROP_TVMODE 10 -#define VO_PROP_MAX_NUM_FRAMES 11 -#define VO_PROP_ZOOM_Y 13 -#define VO_PROP_DISCARD_FRAMES 14 /* not used by drivers */ -#define VO_PROP_WINDOW_WIDTH 15 /* read-only */ -#define VO_PROP_WINDOW_HEIGHT 16 /* read-only */ -#define VO_PROP_BUFS_IN_FIFO 17 /* read-only */ -#define VO_PROP_NUM_STREAMS 18 /* read-only */ -#define VO_NUM_PROPERTIES 19 - -/* number of colors in the overlay palette. Currently limited to 256 - at most, because some alphablend functions use an 8-bit index into - the palette. This should probably be classified as a bug. */ -#define OVL_PALETTE_SIZE 256 - -#define OVL_MAX_OPACITY 0x0f - -/* number of recent frames to keep in memory - these frames are needed by some deinterlace algorithms - FIXME: we need a method to flush the recent frames (new stream) -*/ -#define VO_NUM_RECENT_FRAMES 2 - -/* get_frame flags */ -#define VO_TOP_FIELD 1 -#define VO_BOTTOM_FIELD 2 -#define VO_BOTH_FIELDS (VO_TOP_FIELD | VO_BOTTOM_FIELD) -#define VO_PAN_SCAN_FLAG 4 -#define VO_INTERLACED_FLAG 8 -#define VO_NEW_SEQUENCE_FLAG 16 /* set after MPEG2 Sequence Header Code (used by XvMC) */ - -/* video driver capabilities */ -#define VO_CAP_YV12 0x00000001 /* driver can handle YUV 4:2:0 pictures */ -#define VO_CAP_YUY2 0x00000002 /* driver can handle YUY2 pictures */ -#define VO_CAP_XVMC_MOCOMP 0x00000004 /* driver can use XvMC motion compensation */ -#define VO_CAP_XVMC_IDCT 0x00000008 /* driver can use XvMC idct acceleration */ -#define VO_CAP_UNSCALED_OVERLAY 0x00000010 /* driver can blend overlay at output resolution */ -#define VO_CAP_CROP 0x00000020 /* driver can crop */ -#define VO_CAP_XXMC 0x00000040 /* driver can use extended XvMC */ - - -/* - * vo_driver_s contains the functions every display driver - * has to implement. The vo_new_port function (see below) - * should then be used to construct a vo_port using this - * driver. Some of the function pointers will be copied - * directly into xine_video_port_s, others will be called - * from generic vo functions. - */ - -#define VIDEO_OUT_DRIVER_IFACE_VERSION 22 - -struct vo_driver_s { - - uint32_t (*get_capabilities) (vo_driver_t *self); /* for constants see above */ - - /* - * allocate an vo_frame_t struct, - * the driver must supply the copy, field and dispose functions - */ - vo_frame_t* (*alloc_frame) (vo_driver_t *self); - - /* - * check if the given image fullfills the format specified - * (re-)allocate memory if necessary - */ - void (*update_frame_format) (vo_driver_t *self, vo_frame_t *img, - uint32_t width, uint32_t height, - double ratio, int format, int flags); - - /* display a given frame */ - void (*display_frame) (vo_driver_t *self, vo_frame_t *vo_img); - - /* overlay_begin and overlay_end are used by drivers suporting - * persistent overlays. they can be optimized to update only when - * overlay image has changed. - * - * sequence of operation (pseudo-code): - * overlay_begin(this,img,true_if_something_changed_since_last_blend ); - * while(visible_overlays) - * overlay_blend(this,img,overlay[i]); - * overlay_end(this,img); - * - * any function pointer from this group may be set to NULL. - */ - void (*overlay_begin) (vo_driver_t *self, vo_frame_t *vo_img, int changed); - void (*overlay_blend) (vo_driver_t *self, vo_frame_t *vo_img, vo_overlay_t *overlay); - void (*overlay_end) (vo_driver_t *self, vo_frame_t *vo_img); - - /* - * these can be used by the gui directly: - */ - int (*get_property) (vo_driver_t *self, int property); - int (*set_property) (vo_driver_t *self, - int property, int value); - void (*get_property_min_max) (vo_driver_t *self, - int property, int *min, int *max); - - /* - * general purpose communication channel between gui and driver - * - * this should be used to propagate events, display data, window sizes - * etc. to the driver - */ - int (*gui_data_exchange) (vo_driver_t *self, int data_type, - void *data); - - /* check if a redraw is needed (due to resize) - * this is only used for still frames, normal video playback - * must call that inside display_frame() function. - */ - int (*redraw_needed) (vo_driver_t *self); - - /* - * free all resources, close driver - */ - void (*dispose) (vo_driver_t *self); - - void *node; /* needed by plugin_loader */ -}; - -struct video_driver_class_s { - - /* - * open a new instance of this plugin class - */ - vo_driver_t* (*open_plugin) (video_driver_class_t *self, const void *visual); - - /** - * @brief short human readable identifier for this plugin class - */ - const char *identifier; - - /** - * @brief human readable (verbose = 1 line) description for this plugin class - * - * The description is passed to gettext() to internationalise. - */ - const char *description; - - /** - * @brief Optional non-standard catalog to use with dgettext() for description. - */ - const char *textdomain; - - /* - * free all class-related resources - */ - void (*dispose) (video_driver_class_t *self); -}; - -#define default_video_driver_class_dispose (void (*) (video_driver_class_t *this))free - -typedef struct rle_elem_s { - uint16_t len; - uint16_t color; -} rle_elem_t; - -struct vo_overlay_s { - - rle_elem_t *rle; /* rle code buffer */ - int data_size; /* useful for deciding realloc */ - int num_rle; /* number of active rle codes */ - int x; /* x start of subpicture area */ - int y; /* y start of subpicture area */ - int width; /* width of subpicture area */ - int height; /* height of subpicture area */ - - uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ - uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ - int rgb_clut; /* true if clut was converted to rgb */ - - /* define a highlight area with different colors */ - int hili_top; - int hili_bottom; - int hili_left; - int hili_right; - uint32_t hili_color[OVL_PALETTE_SIZE]; - uint8_t hili_trans[OVL_PALETTE_SIZE]; - int hili_rgb_clut; /* true if clut was converted to rgb */ - - int unscaled; /* true if it should be blended unscaled */ -}; - - -/* API to video_overlay manager - * - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ -struct video_overlay_manager_s { - void (*init) (video_overlay_manager_t *this_gen); - - void (*dispose) (video_overlay_manager_t *this_gen); - - int32_t (*get_handle) (video_overlay_manager_t *this_gen, int object_type ); - - void (*free_handle) (video_overlay_manager_t *this_gen, int32_t handle); - - int32_t (*add_event) (video_overlay_manager_t *this_gen, void *event); - - void (*flush_events) (video_overlay_manager_t *this_gen ); - - int (*redraw_needed) (video_overlay_manager_t *this_gen, int64_t vpts ); - - void (*multiple_overlay_blend) (video_overlay_manager_t *this_gen, int64_t vpts, - vo_driver_t *output, vo_frame_t *vo_img, int enabled); -}; - -/** - * @brief Build a video output port from a given video driver. - * - * @internal - */ -xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h deleted file mode 100644 index 6bb529204..000000000 --- a/src/xine-engine/video_overlay.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef HAVE_VIDEO_OVERLAY_H -#define HAVE_VIDEO_OVERLAY_H - -#ifdef XINE_COMPILE -# include "xine_internal.h" -#else -# include -#endif - -#ifdef __GNUC__ -#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) {y: (_y), cr: (_cr), cb: (_cb)} -#else -#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) { (_cb), (_cr), (_y) } -#endif - -#define MAX_OBJECTS 50 -#define MAX_EVENTS 50 -#define MAX_SHOWING (5 + 16) - -#define OVERLAY_EVENT_NULL 0 -#define OVERLAY_EVENT_SHOW 1 -#define OVERLAY_EVENT_HIDE 2 -#define OVERLAY_EVENT_MENU_BUTTON 3 -#define OVERLAY_EVENT_FREE_HANDLE 8 /* Frees a handle, previous allocated via get_handle */ - -typedef struct video_overlay_object_s { - int32_t handle; /* Used to match Show and Hide events. */ - uint32_t object_type; /* 0=Subtitle, 1=Menu */ - int64_t pts; /* Needed for Menu button compares */ - vo_overlay_t *overlay; /* The image data. */ - uint32_t *palette; /* If NULL, no palette contained in this event. */ - uint32_t palette_type; /* 1 Y'CrCB, 2 R'G'B' */ -} video_overlay_object_t; - -/* This will hold all details of an event item, needed for event queue to function */ -typedef struct video_overlay_event_s { - int64_t vpts; /* Time when event will action. 0 means action now */ -/* Once video_out blend_yuv etc. can take rle_elem_t with Colour, blend and length information. - * we can remove clut and blend from this structure. - * This will allow for many more colours for OSD. - */ - uint32_t event_type; /* Show SPU, Show OSD, Hide etc. */ - video_overlay_object_t object; /* The image data. */ -} video_overlay_event_t; - -video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h deleted file mode 100644 index e502b2f62..000000000 --- a/src/xine-engine/vo_scale.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * vo_scale.h - * - * keeps video scaling information - */ - -#ifndef HAVE_VO_SCALE_H -#define HAVE_VO_SCALE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef XINE_COMPILE -# include "configfile.h" -#else -# include -#endif - -typedef struct { - int x, y; - int w, h; -} vo_scale_rect_t; - -struct vo_scale_s { - - /* true if driver supports frame zooming */ - int support_zoom; - - /* forces direct mapping between frame pixels and screen pixels */ - int scaling_disabled; - - /* size / aspect ratio calculations */ - - /* - * "delivered" size: - * frame dimension / aspect as delivered by the decoder - * used (among other things) to detect frame size changes - * units: frame pixels - */ - int delivered_width; - int delivered_height; - double delivered_ratio; - - /* - * required cropping: - * units: frame pixels - */ - int crop_left; - int crop_right; - int crop_top; - int crop_bottom; - - /* - * displayed part of delivered images, - * taking zoom into account - * units: frame pixels - */ - int displayed_xoffset; - int displayed_yoffset; - int displayed_width; - int displayed_height; - double zoom_factor_x, zoom_factor_y; - - /* - * user's aspect selection - */ - int user_ratio; - - /* - * "gui" size / offset: - * what gui told us about where to display the video - * units: screen pixels - */ - int gui_x, gui_y; - int gui_width, gui_height; - int gui_win_x, gui_win_y; - - /* */ - int force_redraw; - - /* - * video + display pixel aspect - * One pixel of height 1 has this width - * This may be corrected by the driver in order to fit the video seamlessly - */ - double gui_pixel_aspect; - double video_pixel_aspect; - - /* - * "output" size: - * - * this is finally the ideal size "fitted" into the - * gui size while maintaining the aspect ratio - * units: screen pixels - */ - int output_width; - int output_height; - int output_xoffset; - int output_yoffset; - - - /* gui callbacks */ - - void *user_data; - void (*frame_output_cb) (void *user_data, - int video_width, int video_height, - double video_pixel_aspect, - int *dest_x, int *dest_y, - int *dest_width, int *dest_height, - double *dest_pixel_aspect, - int *win_x, int *win_y); - - void (*dest_size_cb) (void *user_data, - int video_width, int video_height, - double video_pixel_aspect, - int *dest_width, int *dest_height, - double *dest_pixel_aspect); - - /* borders */ - vo_scale_rect_t border[4]; - - /* - * border ratios to determine image position in the - * viewport; these are set by user config - */ - double output_horizontal_position; - double output_vertical_position; - -}; - -typedef struct vo_scale_s vo_scale_t; - - -/* - * convert delivered height/width to ideal width/height - * taking into account aspect ratio and zoom factor - */ - -void _x_vo_scale_compute_ideal_size (vo_scale_t *self) XINE_PROTECTED; - - -/* - * make ideal width/height "fit" into the gui - */ - -void _x_vo_scale_compute_output_size (vo_scale_t *self) XINE_PROTECTED; - -/* - * return true if a redraw is needed due resizing, zooming, - * aspect ratio changing, etc. - */ - -int _x_vo_scale_redraw_needed (vo_scale_t *self) XINE_PROTECTED; - -/* - * - */ - -void _x_vo_scale_translate_gui2video(vo_scale_t *self, - int x, int y, - int *vid_x, int *vid_y) XINE_PROTECTED; - -/* - * Returns description of a given ratio code - */ - -char *_x_vo_scale_aspect_ratio_name(int a) XINE_PROTECTED; - -/* - * initialize rescaling struct - */ - -void _x_vo_scale_init(vo_scale_t *self, int support_zoom, - int scaling_disabled, config_values_t *config ) XINE_PROTECTED; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h deleted file mode 100644 index 13b003992..000000000 --- a/src/xine-engine/xine_internal.h +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2000-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef HAVE_XINE_INTERNAL_H -#define HAVE_XINE_INTERNAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * include public part of xine header - */ - -#ifdef XINE_COMPILE -# include "xine.h" -# include "refcounter.h" -# include "input/input_plugin.h" -# include "demuxers/demux.h" -# include "video_out.h" -# include "audio_out.h" -# include "metronom.h" -# include "osd.h" -# include "xineintl.h" -# include "plugin_catalog.h" -# include "video_decoder.h" -# include "audio_decoder.h" -# include "spu_decoder.h" -# include "scratch.h" -# include "broadcaster.h" -# include "io_helper.h" -# include "info_helper.h" -# include "alphablend.h" -#else -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#define XINE_MAX_EVENT_LISTENERS 50 -#define XINE_MAX_EVENT_TYPES 100 -#define XINE_MAX_TICKET_HOLDER_THREADS 64 - -/* used by plugin loader */ -#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION - - -/* - * log constants - */ - -#define XINE_LOG_MSG 0 /* warnings, errors, ... */ -#define XINE_LOG_PLUGIN 1 -#define XINE_LOG_TRACE 2 -#define XINE_LOG_NUM 3 /* # of log buffers defined */ - -#define XINE_STREAM_INFO_MAX 99 - -typedef struct xine_ticket_s xine_ticket_t; - -/* - * the "big" xine struct, holding everything together - */ - -struct xine_s { - - config_values_t *config; - - plugin_catalog_t *plugin_catalog; - - int verbosity; - - int demux_strategy; - char *save_path; - - /* log output that may be presented to the user */ - scratch_buffer_t *log_buffers[XINE_LOG_NUM]; - - xine_list_t *streams; - pthread_mutex_t streams_lock; - - metronom_clock_t *clock; - - /** Handle for libxdg-basedir functions. It's actually an xdgHandle. */ - void * basedir_handle; - -#ifdef XINE_ENGINE_INTERNAL - xine_ticket_t *port_ticket; - pthread_mutex_t log_lock; -#endif -}; - -/* - * xine thread tickets - */ - -struct xine_ticket_s { - - /* the ticket owner must assure to check for ticket revocation in - * intervals of finite length; this means that you must release - * the ticket before any operation that might block - * - * you must never write to this member directly - */ - int ticket_revoked; - - /* apply for a ticket; between acquire and relese of an irrevocable - * ticket (be sure to pair them properly!), it is guaranteed that you - * will never be blocked by ticket revocation */ - void (*acquire)(xine_ticket_t *self, int irrevocable); - - /* give a ticket back */ - void (*release)(xine_ticket_t *self, int irrevocable); - - /* renew a ticket, when it has been revoked, see ticket_revoked above; - * irrevocable must be set to one, if your thread might have acquired - * irrevocable tickets you don't know of; set it to zero only when - * you know that this is impossible */ - void (*renew)(xine_ticket_t *self, int irrevocable); - -#ifdef XINE_ENGINE_INTERNAL - /* allow handing out new tickets */ - void (*issue)(xine_ticket_t *self, int atomic); - - /* revoke all tickets and deny new ones; - * a pair of atomic revoke and issue cannot be interrupted by another - * revocation or by other threads acquiring tickets */ - void (*revoke)(xine_ticket_t *self, int atomic); - - /* behaves like acquire() but doesn't block the calling thread; when - * the thread would have been blocked, 0 is returned otherwise 1 - * this function acquires a ticket even if ticket revocation is active */ - int (*acquire_nonblocking)(xine_ticket_t *self, int irrevocable); - - /* behaves like release() but doesn't block the calling thread; should - * be used in combination with acquire_nonblocking() */ - void (*release_nonblocking)(xine_ticket_t *self, int irrevocable); - - int (*lock_port_rewiring)(xine_ticket_t *self, int ms_timeout); - void (*unlock_port_rewiring)(xine_ticket_t *self); - - void (*dispose)(xine_ticket_t *self); - - pthread_mutex_t lock; - pthread_mutex_t revoke_lock; - pthread_cond_t issued; - pthread_cond_t revoked; - int tickets_granted; - int irrevocable_tickets; - int pending_revocations; - int atomic_revoke; - pthread_t atomic_revoker_thread; - pthread_mutex_t port_rewiring_lock; - struct { - int count; - pthread_t holder; - } *holder_threads; - unsigned holder_thread_count; -#endif -}; - -/* - * xine event queue - */ - -struct xine_event_queue_s { - xine_list_t *events; - pthread_mutex_t lock; - pthread_cond_t new_event; - pthread_cond_t events_processed; - xine_stream_t *stream; - pthread_t *listener_thread; - void *user_data; - xine_event_listener_cb_t callback; - int callback_running; -}; - -/* - * xine_stream - per-stream parts of the xine engine - */ - -struct xine_stream_s { - - /* reference to xine context */ - xine_t *xine; - - /* metronom instance used by current stream */ - metronom_t *metronom; - - /* demuxers use input_plugin to read data */ - input_plugin_t *input_plugin; - - /* used by video decoders */ - xine_video_port_t *video_out; - - /* demuxers send data to video decoders using this fifo */ - fifo_buffer_t *video_fifo; - - /* used by audio decoders */ - xine_audio_port_t *audio_out; - - /* demuxers send data to audio decoders using this fifo */ - fifo_buffer_t *audio_fifo; - - /* provide access to osd api */ - osd_renderer_t *osd_renderer; - - /* master/slave streams */ - xine_stream_t *master; /* usually a pointer to itself */ - xine_stream_t *slave; - - /* input_dvd uses this one. is it possible to add helper functions instead? */ - spu_decoder_t *spu_decoder_plugin; - - /* dxr3 use this one, should be possible to fix to use the port instead */ - vo_driver_t *video_driver; - - /* these definitely should be made private! */ - int audio_channel_auto; - int spu_decoder_streamtype; - int spu_channel_user; - int spu_channel_auto; - int spu_channel_letterbox; - int spu_channel; - - /* current content detection method, see METHOD_BY_xxx */ - int content_detection_method; - -#ifdef XINE_ENGINE_INTERNAL - /* these are private variables, plugins must not access them */ - - int status; - - /* lock controlling speed change access */ - pthread_mutex_t speed_change_lock; - uint32_t ignore_speed_change:1; /*< speed changes during stop can be disastrous */ - uint32_t video_thread_created:1; - uint32_t audio_thread_created:1; - uint32_t first_frame_flag:2; - uint32_t demux_action_pending:1; - uint32_t demux_thread_created:1; - uint32_t demux_thread_running:1; - uint32_t slave_is_subtitle:1; /*< ... and will be automaticaly disposed */ - uint32_t emergency_brake:1; /*< something went really wrong and this stream must be - * stopped. usually due some fatal error on output - * layers as they cannot call xine_stop. */ - uint32_t early_finish_event:1; /*< do not wait fifos get empty before sending event */ - uint32_t gapless_switch:1; /*< next stream switch will be gapless */ - - input_class_t *eject_class; - demux_plugin_t *demux_plugin; - -/* vo_driver_t *video_driver;*/ - pthread_t video_thread; - video_decoder_t *video_decoder_plugin; - extra_info_t *video_decoder_extra_info; - int video_decoder_streamtype; - int video_channel; - - uint32_t audio_track_map[50]; - int audio_track_map_entries; - - int audio_decoder_streamtype; - pthread_t audio_thread; - audio_decoder_t *audio_decoder_plugin; - extra_info_t *audio_decoder_extra_info; - - uint32_t audio_type; - /* *_user: -2 => off - -1 => auto (use *_auto value) - >=0 => respect the user's choice - */ - int audio_channel_user; -/* int audio_channel_auto; */ - -/* spu_decoder_t *spu_decoder_plugin; */ -/* int spu_decoder_streamtype; */ - uint32_t spu_track_map[50]; - int spu_track_map_entries; -/* int spu_channel_user; */ -/* int spu_channel_auto; */ -/* int spu_channel_letterbox; */ - int spu_channel_pan_scan; -/* int spu_channel; */ - - /* lock for public xine player functions */ - pthread_mutex_t frontend_lock; - - /* stream meta information */ - /* NEVER access directly, use helpers (see info_helper.c) */ - pthread_mutex_t info_mutex; - int stream_info_public[XINE_STREAM_INFO_MAX]; - int stream_info[XINE_STREAM_INFO_MAX]; - pthread_mutex_t meta_mutex; - char *meta_info_public[XINE_STREAM_INFO_MAX]; - char *meta_info[XINE_STREAM_INFO_MAX]; - - /* seeking slowdown */ - pthread_mutex_t first_frame_lock; - pthread_cond_t first_frame_reached; - - /* wait for headers sent / stream decoding finished */ - pthread_mutex_t counter_lock; - pthread_cond_t counter_changed; - int header_count_audio; - int header_count_video; - int finished_count_audio; - int finished_count_video; - - /* event mechanism */ - xine_list_t *event_queues; - pthread_mutex_t event_queues_lock; - - /* demux thread stuff */ - pthread_t demux_thread; - pthread_mutex_t demux_lock; - pthread_mutex_t demux_mutex; /* used in _x_demux_... functions to synchronize order of pairwise A/V buffer operations */ - - extra_info_t *current_extra_info; - pthread_mutex_t current_extra_info_lock; - int video_seek_count; - - int delay_finish_event; /* delay event in 1/10 sec units. 0=>no delay, -1=>forever */ - - int slave_affection; /* what operations need to be propagated down to the slave? */ - - int err; - - xine_post_out_t video_source; - xine_post_out_t audio_source; - - broadcaster_t *broadcaster; - - refcounter_t *refcounter; -#endif -}; - -/* when explicitly noted, some functions accept an anonymous stream, - * which is a valid stream that does not want to be addressed. */ -#define XINE_ANON_STREAM ((xine_stream_t *)-1) - - -/* - * private function prototypes: - */ - -int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) XINE_PROTECTED; -int _x_lock_port_rewiring(xine_t *xine, int ms_to_time_out) XINE_PROTECTED; -void _x_unlock_port_rewiring(xine_t *xine) XINE_PROTECTED; -int _x_lock_frontend(xine_stream_t *stream, int ms_to_time_out) XINE_PROTECTED; -void _x_unlock_frontend(xine_stream_t *stream) XINE_PROTECTED; -int _x_query_unprocessed_osd_events(xine_stream_t *stream) XINE_PROTECTED; -int _x_demux_seek(xine_stream_t *stream, off_t start_pos, int start_time, int playing) XINE_PROTECTED; -int _x_continue_stream_processing(xine_stream_t *stream) XINE_PROTECTED; -void _x_trigger_relaxed_frame_drop_mode(xine_stream_t *stream) XINE_PROTECTED; -void _x_reset_relaxed_frame_drop_mode(xine_stream_t *stream) XINE_PROTECTED; - -void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; - -/* report message to UI. usually these are async errors */ - -int _x_message(xine_stream_t *stream, int type, ...) XINE_SENTINEL XINE_PROTECTED; - -/* flush the message queues */ - -void _x_flush_events_queues (xine_stream_t *stream) XINE_PROTECTED; - - -/* find and instantiate input and demux plugins */ - -input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) XINE_PROTECTED; -demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; -demux_plugin_t *_x_find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input) XINE_PROTECTED; -demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input) XINE_PROTECTED; -input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) XINE_PROTECTED; -input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahead_size) XINE_PROTECTED; -void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; -void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t *demux) XINE_PROTECTED; - -/* create decoder fifos and threads */ - -int _x_video_decoder_init (xine_stream_t *stream) XINE_PROTECTED; -void _x_video_decoder_shutdown (xine_stream_t *stream) XINE_PROTECTED; - -int _x_audio_decoder_init (xine_stream_t *stream) XINE_PROTECTED; -void _x_audio_decoder_shutdown (xine_stream_t *stream) XINE_PROTECTED; - -/* extra_info operations */ -void _x_extra_info_reset( extra_info_t *extra_info ) XINE_PROTECTED; - -void _x_extra_info_merge( extra_info_t *dst, extra_info_t *src ) XINE_PROTECTED; - -void _x_get_current_info (xine_stream_t *stream, extra_info_t *extra_info, int size) XINE_PROTECTED; - - -/* demuxer helper functions from demux.c */ - -/* - * Flush audio and video buffers. It is called from demuxers on - * seek/stop, and may be useful when user input changes a stream and - * xine-lib has cached buffers that have yet to be played. - * - * warning: after clearing decoders fifos an absolute discontinuity - * indication must be sent. relative discontinuities are likely - * to cause "jumps" on metronom. - */ -void _x_demux_flush_engine (xine_stream_t *stream) XINE_PROTECTED; - -void _x_demux_control_nop (xine_stream_t *stream, uint32_t flags) XINE_PROTECTED; -void _x_demux_control_newpts (xine_stream_t *stream, int64_t pts, uint32_t flags) XINE_PROTECTED; -void _x_demux_control_headers_done (xine_stream_t *stream) XINE_PROTECTED; -void _x_demux_control_start (xine_stream_t *stream) XINE_PROTECTED; -void _x_demux_control_end (xine_stream_t *stream, uint32_t flags) XINE_PROTECTED; -int _x_demux_start_thread (xine_stream_t *stream) XINE_PROTECTED; -int _x_demux_stop_thread (xine_stream_t *stream) XINE_PROTECTED; -int _x_demux_read_header (input_plugin_t *input, void *buffer, off_t size) XINE_PROTECTED; -int _x_demux_check_extension (const char *mrl, const char *extensions); - -off_t _x_read_abort (xine_stream_t *stream, int fd, char *buf, off_t todo) XINE_PROTECTED; - -int _x_action_pending (xine_stream_t *stream) XINE_PROTECTED; - -void _x_demux_send_data(fifo_buffer_t *fifo, uint8_t *data, int size, - int64_t pts, uint32_t type, uint32_t decoder_flags, - int input_normpos, int input_time, int total_time, - uint32_t frame_number) XINE_PROTECTED; - -int _x_demux_read_send_data(fifo_buffer_t *fifo, input_plugin_t *input, - int size, int64_t pts, uint32_t type, - uint32_t decoder_flags, off_t input_normpos, - int input_time, int total_time, - uint32_t frame_number) XINE_PROTECTED; - -void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative, - const char *mrl, const char *title, - int start_time, int duration) XINE_PROTECTED; - -/* - * MRL escaped-character decoding (overwrites the source string) - */ -void _x_mrl_unescape(char *mrl) XINE_PROTECTED; - -/* - * plugin_loader functions - * - */ - -/* on-demand loading of audio/video/spu decoder plugins */ - -video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; -void _x_free_video_decoder (xine_stream_t *stream, video_decoder_t *decoder) XINE_PROTECTED; -audio_decoder_t *_x_get_audio_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; -void _x_free_audio_decoder (xine_stream_t *stream, audio_decoder_t *decoder) XINE_PROTECTED; -spu_decoder_t *_x_get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; -void _x_free_spu_decoder (xine_stream_t *stream, spu_decoder_t *decoder) XINE_PROTECTED; -/* check for decoder availability - but don't try to initialize it */ -int _x_decoder_available (xine_t *xine, uint32_t buftype) XINE_PROTECTED; - -/* - * load_video_output_plugin - * - * load a specific video output plugin - */ - -vo_driver_t *_x_load_video_output_plugin(xine_t *this, - char *id, int visual_type, void *visual) XINE_PROTECTED; - -/* - * audio output plugin dynamic loading stuff - */ - -/* - * load_audio_output_plugin - * - * load a specific audio output plugin - */ - -ao_driver_t *_x_load_audio_output_plugin (xine_t *self, const char *id) XINE_PROTECTED; - - -void _x_set_speed (xine_stream_t *stream, int speed) XINE_PROTECTED; - -int _x_get_speed (xine_stream_t *stream) XINE_PROTECTED; - -void _x_set_fine_speed (xine_stream_t *stream, int speed) XINE_PROTECTED; - -int _x_get_fine_speed (xine_stream_t *stream) XINE_PROTECTED; - -void _x_select_spu_channel (xine_stream_t *stream, int channel) XINE_PROTECTED; - -int _x_get_audio_channel (xine_stream_t *stream) XINE_PROTECTED; - -int _x_get_spu_channel (xine_stream_t *stream) XINE_PROTECTED; - -/* - * internal events - */ - -/* sent by dvb frontend to inform ts demuxer of new pids */ -#define XINE_EVENT_PIDS_CHANGE 0x80000000 - -/* - * pids change event - inform ts demuxer of new pids - */ -typedef struct { - int vpid; /* video program id */ - int apid; /* audio program id */ -} xine_pids_data_t; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/xine_plugin.h b/src/xine-engine/xine_plugin.h deleted file mode 100644 index 74e7523e9..000000000 --- a/src/xine-engine/xine_plugin.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * generic plugin definitions - */ - -#ifndef XINE_PLUGIN_H -#define XINE_PLUGIN_H - -#define PLUGIN_NONE 0 -#define PLUGIN_INPUT 1 -#define PLUGIN_DEMUX 2 -#define PLUGIN_AUDIO_DECODER 3 -#define PLUGIN_VIDEO_DECODER 4 -#define PLUGIN_SPU_DECODER 5 -#define PLUGIN_AUDIO_OUT 6 -#define PLUGIN_VIDEO_OUT 7 -#define PLUGIN_POST 8 - -#define PLUGIN_TYPE_MAX PLUGIN_POST - -/* this flag may be or'ed with type in order to force preloading the plugin. - * very useful to register config items on xine initialization. - */ -#define PLUGIN_MUST_PRELOAD (1 << 7) - -/* this flag may be or'ed with type to prevent the plugin loader from unloading - * the plugin - */ -#define PLUGIN_NO_UNLOAD (1 << 6) - -#define PLUGIN_TYPE_MASK ((1 << 6) - 1) - -typedef struct { - uint8_t type; /* one of the PLUGIN_* constants above */ - uint8_t API; /* API version supported by this plugin */ - char *id; /* a name that identifies this plugin */ - uint32_t version; /* version number, increased every release */ - const void *special_info; /* plugin-type specific, see structs below */ - void *(*init)(xine_t *, void *); /* init the plugin class */ -} plugin_info_t; - - -/* special_info for a video output plugin */ -typedef struct { - int priority; /* priority of this plugin for auto-probing */ - int visual_type; /* visual type supported by this plugin */ -} vo_info_t; - -/* special info for a audio output plugin */ -typedef struct { - int priority; -} ao_info_t; - -/* special_info for a decoder plugin */ -typedef struct { - uint32_t *supported_types; /* streamtypes this decoder can handle */ - int priority; -} decoder_info_t; - -/* special info for a post plugin */ -typedef struct { - uint32_t type; /* type of the post plugin, use one of XINE_POST_TYPE_* */ -} post_info_t; - -/* special info for a demuxer plugin */ -typedef struct { - int priority; -} demuxer_info_t; - -/* special info for an input plugin */ -typedef struct { - int priority; -} input_info_t; - - -/* register a list of statically linked plugins - * info is a list of plugin_info_t terminated by PLUGIN_NONE - * example: - * plugin_info_t acme_plugin_info[] = { - * { PLUGIN_VIDEO_OUT, 21, "acme", XINE_VERSION_CODE, &vo_info_acme, - * init_class_acme }, - * { PLUGIN_NONE, 0, "", 0, NULL, NULL } - * }; - * - */ -void xine_register_plugins(xine_t *self, plugin_info_t *info) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/xineintl.h b/src/xine-engine/xineintl.h deleted file mode 100644 index 113a033fa..000000000 --- a/src/xine-engine/xineintl.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2000-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef HAVE_XINEINTL_H -#define HAVE_XINEINTL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef ENABLE_NLS -# include -# define _(String) dgettext (XINE_TEXTDOMAIN, String) -# ifdef gettext_noop -# define N_(String) gettext_noop (String) -# else -# define N_(String) (String) -# endif -#else -/* Stubs that do something close enough. */ -# define textdomain(String) (String) -# define gettext(String) (String) -# define dgettext(Domain,Message) (Message) -# define dcgettext(Domain,Message,Type) (Message) -# define ngettext(Singular, Plural, IsPlural) (Singular) -# define bindtextdomain(Domain,Directory) (Domain) -# define _(String) (String) -# define N_(String) (String) -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-utils/Makefile.am b/src/xine-utils/Makefile.am index bacb2720f..30040e318 100644 --- a/src/xine-utils/Makefile.am +++ b/src/xine-utils/Makefile.am @@ -7,19 +7,6 @@ EXTRA_DIST = ppcasm_string.S ppc_asm.tmpl noinst_HEADERS = ppcasm_string.h xine_check.h -xineinclude_HEADERS = \ - attributes.h \ - compat.h \ - xine_buffer.h \ - xineutils.h \ - xmllexer.h \ - xmlparser.h \ - list.h \ - array.h \ - sorted_array.h \ - pool.h \ - ring_buffer.h - noinst_LTLIBRARIES = libxineutils.la if ARCH_PPC diff --git a/src/xine-utils/array.h b/src/xine-utils/array.h deleted file mode 100644 index ae2093823..000000000 --- a/src/xine-utils/array.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Array that can grow automatically when you add elements. - * Inserting an element in the middle of the array implies memory moves. - */ -#ifndef XINE_ARRAY_H -#define XINE_ARRAY_H - -/* Array type */ -typedef struct xine_array_s xine_array_t; - -/* Constructor */ -xine_array_t *xine_array_new(size_t initial_size) XINE_PROTECTED; - -/* Destructor */ -void xine_array_delete(xine_array_t *array) XINE_PROTECTED; - -/* Returns the number of element stored in the array */ -size_t xine_array_size(const xine_array_t *array) XINE_PROTECTED; - -/* Removes all elements from an array */ -void xine_array_clear(xine_array_t *array) XINE_PROTECTED; - -/* Adds the element at the end of the array */ -void xine_array_add(xine_array_t *array, void *value) XINE_PROTECTED; - -/* Inserts an element into an array at the position specified */ -void xine_array_insert(xine_array_t *array, unsigned int position, void *value) XINE_PROTECTED; - -/* Removes one element from an array at the position specified */ -void xine_array_remove(xine_array_t *array, unsigned int position) XINE_PROTECTED; - -/* Get the element at the position specified */ -void *xine_array_get(const xine_array_t *array, unsigned int position) XINE_PROTECTED; - -/* Set the element at the position specified */ -void xine_array_set(xine_array_t *array, unsigned int position, void *value) XINE_PROTECTED; - -#endif - diff --git a/src/xine-utils/attributes.h b/src/xine-utils/attributes.h deleted file mode 100644 index b25c76572..000000000 --- a/src/xine-utils/attributes.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * attributes.h - * Copyright (C) 1999-2000 Aaron Holtzman - * Copyright (C) 2001-2007 xine developers - * - * This file was originally part of mpeg2dec, a free MPEG-2 video stream - * decoder. - * - * mpeg2dec 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. - * - * mpeg2dec 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -/* use gcc attribs to align critical data structures */ - -#ifndef ATTRIBUTE_H_ -#define ATTRIBUTE_H_ - -#ifdef ATTRIBUTE_ALIGNED_MAX -#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) -#else -#define ATTR_ALIGN(align) -#endif - -#ifdef XINE_COMPILE -# include "configure.h" -#endif - -/* Export protected only for libxine functions */ -#if defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_PROTECTED) -# define XINE_PROTECTED __attribute__((__visibility__("protected"))) -#elif defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT) -# define XINE_PROTECTED __attribute__((__visibility__("default"))) -#else -# define XINE_PROTECTED -#endif - -#ifdef SUPPORT_ATTRIBUTE_SENTINEL -# define XINE_SENTINEL __attribute__((__sentinel__)) -#else -# define XINE_SENTINEL -#endif - -#ifndef __attr_unused -# ifdef SUPPORT_ATTRIBUTE_UNUSED -# define __attr_unused __attribute__((__unused__)) -# else -# define __attr_unused -# endif -#endif - -/* Format attributes */ -#ifdef SUPPORT_ATTRIBUTE_FORMAT -# define XINE_FORMAT_PRINTF(fmt,var) __attribute__((__format__(__printf__, fmt, var))) -#else -# define XINE_FORMAT_PRINTF(fmt,var) -#endif -#ifdef SUPPORT_ATTRIBUTE_FORMAT_ARG -# define XINE_FORMAT_PRINTF_ARG(fmt) __attribute__((__format_arg__(fmt))) -#else -# define XINE_FORMAT_PRINTF_ARG(fmt) -#endif - -#ifdef SUPPORT_ATTRIBUTE_PACKED -# define XINE_PACKED __attribute__((packed)) -#else -# define XINE_PACKED -#endif - -#ifdef SUPPORT_ATTRIBUTE_MALLOC -# define XINE_MALLOC __attribute__((__malloc__)) -#else -# define XINE_MALLOC -#endif - -#endif /* ATTRIBUTE_H_ */ diff --git a/src/xine-utils/compat.h b/src/xine-utils/compat.h deleted file mode 100644 index d4b95aeb3..000000000 --- a/src/xine-utils/compat.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000-2001 the xine project - * - * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef XINE_COMPAT_H -#define XINE_COMPAT_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined _MSC_VER -#define __XINE_FUNCTION__ __FILE__ -#elif defined __GNUC__ -#define __XINE_FUNCTION__ __FUNCTION__ -#else -#define __XINE_FUNCTION__ __func__ -#endif - -#ifndef NAME_MAX -#define XINE_NAME_MAX 256 -#else -#define XINE_NAME_MAX NAME_MAX -#endif - -#ifndef PATH_MAX -#define XINE_PATH_MAX 768 -#else -#define XINE_PATH_MAX PATH_MAX -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-utils/list.h b/src/xine-utils/list.h deleted file mode 100644 index e00e30d6c..000000000 --- a/src/xine-utils/list.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Doubly-linked linked list. - * - * Exemples: - * - * Create a list: - * xine_list_t *list = xine_list_new(); - * - * Delete a list: - * xine_list_delete(list); - * - * Walk thru a list: - * xine_list_iterator_t ite = xine_list_front(list); - * while (ite) { - * _useful code here_ - * ite = xine_list_next(list, ite); - * } - * - * The list elements are managed using memory chunks and a free list. The first - * chunk contains 32 elements, each following chunk is two time as big as the - * previous one, with a limit of 64K elements. - */ -#ifndef XINE_LIST_H -#define XINE_LIST_H - -/* Doubly-linked list type */ -typedef struct xine_list_s xine_list_t; - -/* List iterator */ -typedef void* xine_list_iterator_t; - -/* Constructor */ -xine_list_t *xine_list_new(void) XINE_PROTECTED; - -/* Destructor */ -void xine_list_delete(xine_list_t *list) XINE_PROTECTED; - -/* Returns the number of element stored in the list */ -unsigned int xine_list_size(xine_list_t *list) XINE_PROTECTED; - -/* Returns true if the number of elements is zero, false otherwise */ -unsigned int xine_list_empty(xine_list_t *list) XINE_PROTECTED; - -/* Adds the element at the beginning of the list */ -void xine_list_push_front(xine_list_t *list, void *value) XINE_PROTECTED; - -/* Adds the element at the end of the list */ -void xine_list_push_back(xine_list_t *list, void *value) XINE_PROTECTED; - -/* Remove all elements from a list */ -void xine_list_clear(xine_list_t *list) XINE_PROTECTED; - -/* Insert the element elem into the list at the position specified by the - iterator (before the element, if any, that was previously at the iterator's - position). The return value is an iterator that specifies the position of - the inserted element. */ -xine_list_iterator_t xine_list_insert(xine_list_t *list, - xine_list_iterator_t position, - void *value) XINE_PROTECTED; - -/* Remove one element from a list.*/ -void xine_list_remove(xine_list_t *list, xine_list_iterator_t position) XINE_PROTECTED; - -/* Returns an iterator that references the first element of the list */ -xine_list_iterator_t xine_list_front(xine_list_t *list) XINE_PROTECTED; - -/* Returns an iterator that references the last element of the list */ -xine_list_iterator_t xine_list_back(xine_list_t *list) XINE_PROTECTED; - -/* Perform a linear search of a given value, and returns an iterator that - references this value or NULL if not found */ -xine_list_iterator_t xine_list_find(xine_list_t *list, void *value) XINE_PROTECTED; - -/* Increments the iterator's value, so it specifies the next element in the list - or NULL at the end of the list */ -xine_list_iterator_t xine_list_next(xine_list_t *list, xine_list_iterator_t ite) XINE_PROTECTED; - -/* Increments the iterator's value, so it specifies the previous element in the list - or NULL at the beginning of the list */ -xine_list_iterator_t xine_list_prev(xine_list_t *list, xine_list_iterator_t ite) XINE_PROTECTED; - -/* Returns the value at the position specified by the iterator */ -void *xine_list_get_value(xine_list_t *list, xine_list_iterator_t ite) XINE_PROTECTED; - -#endif - diff --git a/src/xine-utils/pool.h b/src/xine-utils/pool.h deleted file mode 100644 index 918da82a2..000000000 --- a/src/xine-utils/pool.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Object Pool - */ - -#include -#include - -typedef struct xine_pool_s xine_pool_t; - -/* Creates a new pool - * object_size: sizeof(your struct) - * create_object: function called to create an object (can be NULL) - * prepare_object: function called to prepare an object to returned to the client (can be NULL) - * return_object: function called to prepare an object to returned to the pool (can be NULL) - * delete_object: function called to delete an object (can be NULL) - */ -xine_pool_t *xine_pool_new(size_t object_size, - void (create_object)(void *object), - void (prepare_object)(void *object), - void (return_object)(void *object), - void (delete_object)(void *object)) XINE_PROTECTED; - -/* Deletes a pool */ -void xine_pool_delete(xine_pool_t *pool) XINE_PROTECTED; - -/* Get an object from the pool */ -void *xine_pool_get(xine_pool_t *pool) XINE_PROTECTED; - -/* Returns an object to the pool */ -void xine_pool_put(xine_pool_t *pool, void *object) XINE_PROTECTED; diff --git a/src/xine-utils/ring_buffer.h b/src/xine-utils/ring_buffer.h deleted file mode 100644 index efcffd3b7..000000000 --- a/src/xine-utils/ring_buffer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Fifo + Ring Buffer - */ -typedef struct xine_ring_buffer_s xine_ring_buffer_t; - -/* Creates a new ring buffer */ -xine_ring_buffer_t *xine_ring_buffer_new(size_t size) XINE_PROTECTED; - -/* Deletes a ring buffer */ -void xine_ring_buffer_delete(xine_ring_buffer_t *ring_buffer) XINE_PROTECTED; - -/* Returns a new chunk of the specified size */ -/* Might block if the ring buffer is full */ -void *xine_ring_buffer_alloc(xine_ring_buffer_t *ring_buffer, size_t size) XINE_PROTECTED; - -/* Put a chunk into the ring */ -void xine_ring_buffer_put(xine_ring_buffer_t *ring_buffer, void *chunk) XINE_PROTECTED; - -/* Get a chunk of a specified size from the ring buffer - * Might block if the ring buffer is empty - * param size: the desired size - * param rsize: the size of the chunk returned - * rsize is not equal to size at the end of stream, the caller MUST check - * rsize value. - */ -void *xine_ring_buffer_get(xine_ring_buffer_t *ring_buffer, size_t size, size_t *rsize) XINE_PROTECTED; - -/* Releases the chunk, makes memory available for the alloc function */ -void xine_ring_buffer_release(xine_ring_buffer_t *ring_buffer, void *chunk) XINE_PROTECTED; - -/* Closes the ring buffer - * The writer uses this function to signal the end of stream to the reader. - * The reader MUST check the rsize value returned by the get function. - */ -void xine_ring_buffer_close(xine_ring_buffer_t *ring_buffer) XINE_PROTECTED; - - diff --git a/src/xine-utils/sorted_array.h b/src/xine-utils/sorted_array.h deleted file mode 100644 index a1894eca3..000000000 --- a/src/xine-utils/sorted_array.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Sorted array which grows automatically when you add elements. - * A binary search is used to find the position of a new element. - * - * Example: - * Let's create de comparison method for integers: - * - * int int_comparator(void *a, void *b) { - * if ((int)a < (int)b) { - * return -1; - * } else if ((int)a == (int)b) { - * return 0; - * } else { - * return 1; - * } - * } - * - * Create a sorted array for integers: - * xine_sarray_t *sarray = xine_sarray_new(10, int_comparator); - * - * Add elements: - * xine_sarray_add(sarray, (void*)4); - * xine_sarray_add(sarray, (void*)28); - * xine_sarray_add(sarray, (void*)7); - * - * Find an element: - * int pos = xine_sarray_binary_search(sarray, (void*)7); - * if (pos >= 0) - * FOUND - * else - * NOT FOUND - * - * Delete the array: - * xine_sarray_delete(sarray); - */ -#ifndef XINE_SORTED_ARRAY_H -#define XINE_SORTED_ARRAY_H - -#include "array.h" - -/* Array type */ -typedef struct xine_sarray_s xine_sarray_t; - -/* Array element comparator */ -typedef int (*xine_sarray_comparator_t)(void*, void*); - -/* Constructor */ -xine_sarray_t *xine_sarray_new(size_t initial_size, xine_sarray_comparator_t comparator) XINE_PROTECTED; - -/* Destructor */ -void xine_sarray_delete(xine_sarray_t *sarray) XINE_PROTECTED; - -/* Returns the number of element stored in the array */ -size_t xine_sarray_size(const xine_sarray_t *sarray) XINE_PROTECTED; - -/* Removes all elements from an array */ -void xine_sarray_clear(xine_sarray_t *sarray) XINE_PROTECTED; - -/* Adds the element into the array - Returns the insertion position */ -int xine_sarray_add(xine_sarray_t *sarray, void *value) XINE_PROTECTED; - -/* Removes one element from an array at the position specified */ -void xine_sarray_remove(xine_sarray_t *sarray, unsigned int position) XINE_PROTECTED; - -/* Get the element at the position specified */ -void *xine_sarray_get(xine_sarray_t *sarray, unsigned int position) XINE_PROTECTED; - -/* Returns the index of the search key, if it is contained in the list. - Otherwise, (-(insertion point) - 1) or ~(insertion point). - The insertion point is defined as the point at which the key would be - inserted into the array. */ -int xine_sarray_binary_search(xine_sarray_t *sarray, void *key) XINE_PROTECTED; - -#endif - diff --git a/src/xine-utils/xine_buffer.h b/src/xine-utils/xine_buffer.h deleted file mode 100644 index 84511bd1b..000000000 --- a/src/xine-utils/xine_buffer.h +++ /dev/null @@ -1,136 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * - * generic dynamic buffer functions. The goals - * of these functions are (in fact many of these points - * are todos): - * - dynamic allocation and reallocation depending - * on the size of data written to it. - * - fast and transparent access to the data. - * The user sees only the raw data chunk as it is - * returned by the well-known malloc function. - * This is necessary since not all data-accessing - * functions can be wrapped here. - * - some additional health checks are made during - * development (eg boundary checks after direct - * access to a buffer). This can be turned off in - * production state for higher performance. - * - A lot of convenient string and memory manipulation - * functions are implemented here, where the user - * do not have to care about memory chunk sizes. - * - Some garbage collention could be implemented as well; - * i think of a global structure containing infos - * about all allocated chunks. This must be implemented - * in a thread-save way... - * - * Here are some drawbacks (aka policies): - * - The user must not pass indexed buffers to xine_buffer_* - * functions. - * - The pointers passed to xine_buffer_* functions may change - * (eg during reallocation). The user must respect that. - */ - -#ifndef HAVE_XINE_BUFFER_H -#define HAVE_XINE_BUFFER_H - -#ifdef XINE_COMPILE -# include -#else -# include -#endif - -/* - * returns an initialized pointer to a buffer. - * The buffer will be allocated in blocks of - * chunk_size bytes. This will prevent permanent - * reallocation on slow growing buffers. - */ -void *xine_buffer_init(int chunk_size) XINE_PROTECTED; - -/* - * frees a buffer, the macro ensures, that a freed - * buffer pointer is set to NULL - */ -#define xine_buffer_free(buf) buf=_xine_buffer_free(buf) -void *_xine_buffer_free(void *buf) XINE_PROTECTED; - -/* - * duplicates a buffer - */ -void *xine_buffer_dup(const void *buf) XINE_PROTECTED; - -/* - * will copy len bytes of data into buf at position index. - */ -#define xine_buffer_copyin(buf,i,data,len) \ - buf=_xine_buffer_copyin(buf,i,data,len) -void *_xine_buffer_copyin(void *buf, int index, const void *data, int len) XINE_PROTECTED; - -/* - * will copy len bytes out of buf+index into data. - * no checks are made in data. It is treated as an ordinary - * user-malloced data chunk. - */ -void xine_buffer_copyout(const void *buf, int index, void *data, int len) XINE_PROTECTED; - -/* - * set len bytes in buf+index to b. - */ -#define xine_buffer_set(buf,i,b,len) \ - buf=_xine_buffer_set(buf,i,b,len) -void *_xine_buffer_set(void *buf, int index, uint8_t b, int len) XINE_PROTECTED; - -/* - * concatenates given buf (which should contain a null terminated string) - * with another string. - */ -#define xine_buffer_strcat(buf,data) \ - buf=_xine_buffer_strcat(buf,data) -void *_xine_buffer_strcat(void *buf, const char *data) XINE_PROTECTED; - -/* - * copies given string to buf+index - */ -#define xine_buffer_strcpy(buf,index,data) \ - buf=_xine_buffer_strcpy(buf,index,data) -void *_xine_buffer_strcpy(void *buf, int index, const char *data) XINE_PROTECTED; - -/* - * returns a pointer to the first occurence of ch. - * note, that the returned pointer cannot be used - * in any other xine_buffer_* functions. - */ -char *xine_buffer_strchr(const void *buf, int ch) XINE_PROTECTED; - -/* - * get allocated memory size - */ -int xine_buffer_get_size(const void *buf) XINE_PROTECTED; - -/* - * ensures a specified buffer size if the user want to - * write directly to the buffer. Normally the special - * access functions defined here should be used. - */ -#define xine_buffer_ensure_size(buf,data) \ - buf=_xine_buffer_ensure_size(buf,data) -void *_xine_buffer_ensure_size(void *buf, int size) XINE_PROTECTED; - -#endif diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h deleted file mode 100644 index 4ff87e87c..000000000 --- a/src/xine-utils/xineutils.h +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ -#ifndef XINEUTILS_H -#define XINEUTILS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -#ifdef XINE_COMPILE -# include -# include "attributes.h" -# include "compat.h" -# include "xmlparser.h" -# include "xine_buffer.h" -# include "configfile.h" -# include "list.h" -# include "array.h" -# include "sorted_array.h" -#else -# ifdef WIN32 -# include -# else -# include -# endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include - -/* - * Mark exported data symbols for link engine library clients with older - * Win32 compilers - */ -#if defined(WIN32) && !defined(XINE_LIBRARY_COMPILE) -# define DL_IMPORT __declspec(dllimport) -# define extern DL_IMPORT extern -#endif - - /* - * debugable mutexes - */ - - typedef struct { - pthread_mutex_t mutex; - char id[80]; - char *locked_by; - } xine_mutex_t; - - int xine_mutex_init (xine_mutex_t *mutex, const pthread_mutexattr_t *mutexattr, - const char *id) XINE_PROTECTED; - - int xine_mutex_lock (xine_mutex_t *mutex, const char *who) XINE_PROTECTED; - int xine_mutex_unlock (xine_mutex_t *mutex, const char *who) XINE_PROTECTED; - int xine_mutex_destroy (xine_mutex_t *mutex) XINE_PROTECTED; - - - - /* CPU Acceleration */ - -/* - * The type of an value that fits in an MMX register (note that long - * long constant values MUST be suffixed by LL and unsigned long long - * values by ULL, lest they be truncated by the compiler) - */ - -/* generic accelerations */ -#define MM_ACCEL_MLIB 0x00000001 - -/* x86 accelerations */ -#define MM_ACCEL_X86_MMX 0x80000000 -#define MM_ACCEL_X86_3DNOW 0x40000000 -#define MM_ACCEL_X86_MMXEXT 0x20000000 -#define MM_ACCEL_X86_SSE 0x10000000 -#define MM_ACCEL_X86_SSE2 0x08000000 - -/* powerpc accelerations and features */ -#define MM_ACCEL_PPC_ALTIVEC 0x04000000 -#define MM_ACCEL_PPC_CACHE32 0x02000000 - -/* SPARC accelerations */ - -#define MM_ACCEL_SPARC_VIS 0x01000000 -#define MM_ACCEL_SPARC_VIS2 0x00800000 - -/* x86 compat defines */ -#define MM_MMX MM_ACCEL_X86_MMX -#define MM_3DNOW MM_ACCEL_X86_3DNOW -#define MM_MMXEXT MM_ACCEL_X86_MMXEXT -#define MM_SSE MM_ACCEL_X86_SSE -#define MM_SSE2 MM_ACCEL_X86_SSE2 - -uint32_t xine_mm_accel (void) XINE_PROTECTED; - -#if defined(ARCH_X86) || defined(ARCH_X86_64) - -typedef union { - int64_t q; /* Quadword (64-bit) value */ - uint64_t uq; /* Unsigned Quadword */ - int d[2]; /* 2 Doubleword (32-bit) values */ - unsigned int ud[2]; /* 2 Unsigned Doubleword */ - short w[4]; /* 4 Word (16-bit) values */ - unsigned short uw[4]; /* 4 Unsigned Word */ - char b[8]; /* 8 Byte (8-bit) values */ - unsigned char ub[8]; /* 8 Unsigned Byte */ - float s[2]; /* Single-precision (32-bit) value */ -} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ - - - -#define mmx_i2r(op,imm,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "i" (imm) ) - -#define mmx_m2r(op,mem,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "m" (mem)) - -#define mmx_r2m(op,reg,mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=m" (mem) \ - : /* nothing */ ) - -#define mmx_r2r(op,regs,regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - - -#define emms() __asm__ __volatile__ ("emms") - -#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) -#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) -#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) - -#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) -#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) -#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) - -#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) -#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) -#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) -#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) - -#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) -#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) - -#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) -#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) -#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) -#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) -#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) -#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) - -#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) -#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) -#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) -#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) - -#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) -#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) -#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) -#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) - -#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) -#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) - -#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) -#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) - -#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) -#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) -#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) -#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) -#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) -#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) - -#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) -#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) -#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) -#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) -#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) -#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) - -#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) -#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) - -#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) -#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) - -#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) -#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) - -#define por_m2r(var,reg) mmx_m2r (por, var, reg) -#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) - -#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) -#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) -#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) -#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) -#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) -#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) -#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) -#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) -#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) - -#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) -#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) -#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) -#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) -#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) -#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) - -#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) -#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) -#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) -#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) -#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) -#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) -#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) -#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) -#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) - -#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) -#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) -#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) -#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) -#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) -#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) - -#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) -#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) -#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) -#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) - -#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) -#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) -#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) -#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) - -#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) -#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) -#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) -#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) -#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) -#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) - -#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) -#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) -#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) -#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) -#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) -#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) - -#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) -#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) - - -/* 3DNOW extensions */ - -#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) -#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) - - -/* AMD MMX extensions - also available in intel SSE */ - - -#define mmx_m2ri(op,mem,reg,imm) \ - __asm__ __volatile__ (#op " %1, %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem), "X" (imm)) -#define mmx_r2ri(op,regs,regd,imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define mmx_fetch(mem,hint) \ - __asm__ __volatile__ ("prefetch" #hint " %0" \ - : /* nothing */ \ - : "X" (mem)) - - -#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) - -#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) - -#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) -#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) -#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) -#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) - -#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) - -#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) - -#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) -#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) - -#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) -#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) - -#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) -#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) - -#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) -#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) - -#define pmovmskb(mmreg,reg) \ - __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) - -#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) -#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) - -#define prefetcht0(mem) mmx_fetch (mem, t0) -#define prefetcht1(mem) mmx_fetch (mem, t1) -#define prefetcht2(mem) mmx_fetch (mem, t2) -#define prefetchnta(mem) mmx_fetch (mem, nta) - -#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) -#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) - -#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) -#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) - -#define sfence() __asm__ __volatile__ ("sfence\n\t") - -typedef union { - float sf[4]; /* Single-precision (32-bit) value */ -} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */ - - -#define sse_i2r(op, imm, reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (imm) ) - -#define sse_m2r(op, mem, reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem)) - -#define sse_r2m(op, reg, mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=X" (mem) \ - : /* nothing */ ) - -#define sse_r2r(op, regs, regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - -#define sse_r2ri(op, regs, regd, imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define sse_m2ri(op, mem, reg, subop) \ - __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \ - : /* nothing */ \ - : "X" (mem)) - - -#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg) -#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var) -#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd) - -#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var) - -#define movups_m2r(var, reg) sse_m2r(movups, var, reg) -#define movups_r2m(reg, var) sse_r2m(movups, reg, var) -#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd) - -#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd) - -#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd) - -#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg) -#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var) - -#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg) -#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var) - -#define movss_m2r(var, reg) sse_m2r(movss, var, reg) -#define movss_r2m(reg, var) sse_r2m(movss, reg, var) -#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd) - -#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index) -#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index) - -#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg) -#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg) - -#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg) -#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg) - -#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg) -#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg) - -#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg) -#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg) - -#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) -#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) - -#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) -#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) - -#define movmskps(xmmreg, reg) \ - __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) - -#define addps_m2r(var, reg) sse_m2r(addps, var, reg) -#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd) - -#define addss_m2r(var, reg) sse_m2r(addss, var, reg) -#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd) - -#define subps_m2r(var, reg) sse_m2r(subps, var, reg) -#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd) - -#define subss_m2r(var, reg) sse_m2r(subss, var, reg) -#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd) - -#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg) -#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd) - -#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg) -#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd) - -#define divps_m2r(var, reg) sse_m2r(divps, var, reg) -#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd) - -#define divss_m2r(var, reg) sse_m2r(divss, var, reg) -#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd) - -#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg) -#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd) - -#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg) -#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd) - -#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg) -#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd) - -#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg) -#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd) - -#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg) -#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd) - -#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg) -#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd) - -#define andps_m2r(var, reg) sse_m2r(andps, var, reg) -#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd) - -#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg) -#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd) - -#define orps_m2r(var, reg) sse_m2r(orps, var, reg) -#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd) - -#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg) -#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd) - -#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg) -#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd) - -#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg) -#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd) - -#define minps_m2r(var, reg) sse_m2r(minps, var, reg) -#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd) - -#define minss_m2r(var, reg) sse_m2r(minss, var, reg) -#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd) - -#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op) -#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op) - -#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0) -#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0) - -#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1) -#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1) - -#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2) -#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2) - -#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3) -#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3) - -#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4) -#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4) - -#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5) -#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5) - -#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6) -#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6) - -#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7) -#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7) - -#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op) -#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op) - -#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0) -#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0) - -#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1) -#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1) - -#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2) -#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2) - -#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3) -#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3) - -#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4) -#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4) - -#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5) -#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5) - -#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6) -#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6) - -#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7) -#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7) - -#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg) -#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd) - -#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg) -#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd) - -#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg) -#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd) - -#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg) -#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd) - -#define fxrstor(mem) \ - __asm__ __volatile__ ("fxrstor %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define fxsave(mem) \ - __asm__ __volatile__ ("fxsave %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define stmxcsr(mem) \ - __asm__ __volatile__ ("stmxcsr %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define ldmxcsr(mem) \ - __asm__ __volatile__ ("ldmxcsr %0" \ - : /* nothing */ \ - : "X" (mem)) -#endif /*ARCH_X86 */ - - - /* Optimized/fast memcpy */ - -extern void *(* xine_fast_memcpy)(void *to, const void *from, size_t len) XINE_PROTECTED; - -#ifdef HAVE_XINE_INTERNAL_H -/* Benchmark available memcpy methods */ -void xine_probe_fast_memcpy(xine_t *xine) XINE_PROTECTED; -#endif - - -/* - * Debug stuff - */ -/* - * profiling (unworkable in non DEBUG isn't defined) - */ -void xine_profiler_init (void) XINE_PROTECTED; -int xine_profiler_allocate_slot (const char *label) XINE_PROTECTED; -void xine_profiler_start_count (int id) XINE_PROTECTED; -void xine_profiler_stop_count (int id) XINE_PROTECTED; -void xine_profiler_print_results (void) XINE_PROTECTED; - -/* - * Allocate and clean memory size_t 'size', then return the pointer - * to the allocated memory. - */ -void *xine_xmalloc(size_t size) XINE_MALLOC XINE_PROTECTED; - -void *xine_xcalloc(size_t nmemb, size_t size) XINE_MALLOC XINE_PROTECTED; - -/* - * Same as above, but memory is aligned to 'alignement'. - * **base is used to return pointer to un-aligned memory, use - * this to free the mem chunk - */ -void *xine_xmalloc_aligned(size_t alignment, size_t size, void **base) XINE_PROTECTED; - -/* - * Get user home directory. - */ -const char *xine_get_homedir(void) XINE_PROTECTED; - -#if defined(WIN32) || defined(__CYGWIN__) -/* - * Get other xine directories. - */ -const char *xine_get_plugindir(void) XINE_PROTECTED; -const char *xine_get_fontdir(void) XINE_PROTECTED; -const char *xine_get_localedir(void) XINE_PROTECTED; -#endif - -/* - * Clean a string (remove spaces and '=' at the begin, - * and '\n', '\r' and spaces at the end. - */ -char *xine_chomp (char *str) XINE_PROTECTED; - -/* - * A thread-safe usecond sleep - */ -void xine_usec_sleep(unsigned usec) XINE_PROTECTED; - -/* compatibility macros */ -#define xine_strpbrk(S, ACCEPT) strpbrk((S), (ACCEPT)) -#define xine_strsep(STRINGP, DELIM) strsep((STRINGP), (DELIM)) -#define xine_setenv(NAME, VAL, XX) setenv((NAME), (VAL), (XX)) - -/* - * Color Conversion Utility Functions - * The following data structures and functions facilitate the conversion - * of RGB images to packed YUV (YUY2) images. There are also functions to - * convert from YUV9 -> YV12. All of the meaty details are written in - * color.c. - */ - -typedef struct yuv_planes_s { - - unsigned char *y; - unsigned char *u; - unsigned char *v; - unsigned int row_width; /* frame width */ - unsigned int row_count; /* frame height */ - -} yuv_planes_t; - -void init_yuv_conversion(void) XINE_PROTECTED; -void init_yuv_planes(yuv_planes_t *yuv_planes, int width, int height) XINE_PROTECTED; -void free_yuv_planes(yuv_planes_t *yuv_planes) XINE_PROTECTED; - -extern void (*yuv444_to_yuy2) - (const yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int pitch) XINE_PROTECTED; -extern void (*yuv9_to_yv12) - (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, - const unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, - const unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, - int width, int height) XINE_PROTECTED; -extern void (*yuv411_to_yv12) - (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, - const unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, - const unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, - int width, int height) XINE_PROTECTED; -extern void (*yv12_to_yuy2) - (const unsigned char *y_src, int y_src_pitch, - const unsigned char *u_src, int u_src_pitch, - const unsigned char *v_src, int v_src_pitch, - unsigned char *yuy2_map, int yuy2_pitch, - int width, int height, int progressive) XINE_PROTECTED; -extern void (*yuy2_to_yv12) - (const unsigned char *yuy2_map, int yuy2_pitch, - unsigned char *y_dst, int y_dst_pitch, - unsigned char *u_dst, int u_dst_pitch, - unsigned char *v_dst, int v_dst_pitch, - int width, int height) XINE_PROTECTED; - -#define SCALEFACTOR 65536 -#define CENTERSAMPLE 128 - -#define COMPUTE_Y(r, g, b) \ - (unsigned char) \ - ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR) -#define COMPUTE_U(r, g, b) \ - (unsigned char) \ - ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) -#define COMPUTE_V(r, g, b) \ - (unsigned char) \ - ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) - -#define UNPACK_BGR15(packed_pixel, r, g, b) \ - b = (packed_pixel & 0x7C00) >> 7; \ - g = (packed_pixel & 0x03E0) >> 2; \ - r = (packed_pixel & 0x001F) << 3; - -#define UNPACK_BGR16(packed_pixel, r, g, b) \ - b = (packed_pixel & 0xF800) >> 8; \ - g = (packed_pixel & 0x07E0) >> 3; \ - r = (packed_pixel & 0x001F) << 3; - -#define UNPACK_RGB15(packed_pixel, r, g, b) \ - r = (packed_pixel & 0x7C00) >> 7; \ - g = (packed_pixel & 0x03E0) >> 2; \ - b = (packed_pixel & 0x001F) << 3; - -#define UNPACK_RGB16(packed_pixel, r, g, b) \ - r = (packed_pixel & 0xF800) >> 8; \ - g = (packed_pixel & 0x07E0) >> 3; \ - b = (packed_pixel & 0x001F) << 3; - -extern int y_r_table[256] XINE_PROTECTED; -extern int y_g_table[256] XINE_PROTECTED; -extern int y_b_table[256] XINE_PROTECTED; - -extern int u_r_table[256] XINE_PROTECTED; -extern int u_g_table[256] XINE_PROTECTED; -extern int u_b_table[256] XINE_PROTECTED; - -extern int v_r_table[256] XINE_PROTECTED; -extern int v_g_table[256] XINE_PROTECTED; -extern int v_b_table[256] XINE_PROTECTED; - -/* frame copying functions */ -extern void yv12_to_yv12 - (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dst, int y_dst_pitch, - const unsigned char *u_src, int u_src_pitch, unsigned char *u_dst, int u_dst_pitch, - const unsigned char *v_src, int v_src_pitch, unsigned char *v_dst, int v_dst_pitch, - int width, int height) XINE_PROTECTED; -extern void yuy2_to_yuy2 - (const unsigned char *src, int src_pitch, - unsigned char *dst, int dst_pitch, - int width, int height) XINE_PROTECTED; - -/* print a hexdump of the given data */ -void xine_hexdump (const void *buf, int length) XINE_PROTECTED; - -/* - * Optimization macros for conditions - * Taken from the FIASCO L4 microkernel sources - */ -#if !defined(__GNUC__) || __GNUC__ < 3 -# define EXPECT_TRUE(x) (x) -# define EXPECT_FALSE(x) (x) -#else -# define EXPECT_TRUE(x) __builtin_expect((x),1) -# define EXPECT_FALSE(x) __builtin_expect((x),0) -#endif - -#ifdef NDEBUG -#define _x_assert(exp) \ - do { \ - if (!(exp)) \ - fprintf(stderr, "assert: %s:%d: %s: Assertion `%s' failed.\n", \ - __FILE__, __LINE__, __XINE_FUNCTION__, #exp); \ - } while(0) -#else -#define _x_assert(exp) \ - do { \ - if (!(exp)) { \ - fprintf(stderr, "assert: %s:%d: %s: Assertion `%s' failed.\n", \ - __FILE__, __LINE__, __XINE_FUNCTION__, #exp); \ - abort(); \ - } \ - } while(0) -#endif - -#define _x_abort() \ - do { \ - fprintf(stderr, "abort: %s:%d: %s: Aborting.\n", \ - __FILE__, __LINE__, __XINE_FUNCTION__); \ - abort(); \ - } while(0) - - -/****** logging with xine **********************************/ - -#ifndef LOG_MODULE - #define LOG_MODULE __FILE__ -#endif /* LOG_MODULE */ - -#define LOG_MODULE_STRING printf("%s: ", LOG_MODULE ); - -#ifdef LOG_VERBOSE - #define LONG_LOG_MODULE_STRING \ - printf("%s: (%s:%d) ", LOG_MODULE, __XINE_FUNCTION__, __LINE__ ); -#else - #define LONG_LOG_MODULE_STRING LOG_MODULE_STRING -#endif /* LOG_VERBOSE */ - -#ifdef LOG - #ifdef __GNUC__ - #define lprintf(fmt, args...) \ - do { \ - LONG_LOG_MODULE_STRING \ - printf(fmt, ##args); \ - fflush(stdout); \ - } while(0) - #else /* __GNUC__ */ - #ifdef _MSC_VER - #define lprintf(fmtargs) \ - do { \ - LONG_LOG_MODULE_STRING \ - printf("%s", fmtargs); \ - fflush(stdout); \ - } while(0) - #else /* _MSC_VER */ - #define lprintf(...) \ - do { \ - LONG_LOG_MODULE_STRING \ - printf(__VA_ARGS__); \ - fflush(stdout); \ - } while(0) - #endif /* _MSC_VER */ - #endif /* __GNUC__ */ -#else /* LOG */ - #ifdef __GNUC__ - #define lprintf(fmt, args...) do {} while(0) - #else - #ifdef _MSC_VER -void __inline lprintf(const char * fmt, ...) {} - #else - #define lprintf(...) do {} while(0) - #endif /* _MSC_VER */ - #endif /* __GNUC__ */ -#endif /* LOG */ - -#ifdef __GNUC__ - #define llprintf(cat, fmt, args...) \ - do{ \ - if(cat){ \ - LONG_LOG_MODULE_STRING \ - printf( fmt, ##args ); \ - } \ - }while(0) -#else -#ifdef _MSC_VER - #define llprintf(cat, fmtargs) \ - do{ \ - if(cat){ \ - LONG_LOG_MODULE_STRING \ - printf( "%s", fmtargs ); \ - } \ - }while(0) -#else - #define llprintf(cat, ...) \ - do{ \ - if(cat){ \ - LONG_LOG_MODULE_STRING \ - printf( __VA_ARGS__ ); \ - } \ - }while(0) -#endif /* _MSC_VER */ -#endif /* __GNUC__ */ - -#ifdef __GNUC__ - #define xprintf(xine, verbose, fmt, args...) \ - do { \ - if((xine) && (xine)->verbosity >= verbose){ \ - xine_log(xine, XINE_LOG_TRACE, fmt, ##args); \ - } \ - } while(0) -#else -#ifdef _MSC_VER -void xine_xprintf(xine_t *xine, int verbose, const char *fmt, ...); - #define xprintf xine_xprintf -#else - #define xprintf(xine, verbose, ...) \ - do { \ - if((xine) && (xine)->verbosity >= verbose){ \ - xine_log(xine, XINE_LOG_TRACE, __VA_ARGS__); \ - } \ - } while(0) -#endif /* _MSC_VER */ -#endif /* __GNUC__ */ - -/* time measuring macros for profiling tasks */ - -#ifdef DEBUG -# define XINE_PROFILE(function) \ - do { \ - struct timeval current_time; \ - double dtime; \ - gettimeofday(¤t_time, NULL); \ - dtime = -(current_time.tv_sec + (current_time.tv_usec / 1000000.0)); \ - function; \ - gettimeofday(¤t_time, NULL); \ - dtime += current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ - printf("%s: (%s:%d) took %lf seconds\n", \ - LOG_MODULE, __XINE_FUNCTION__, __LINE__, dtime); \ - } while(0) -# define XINE_PROFILE_ACCUMULATE(function) \ - do { \ - struct timeval current_time; \ - static double dtime = 0; \ - gettimeofday(¤t_time, NULL); \ - dtime -= current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ - function; \ - gettimeofday(¤t_time, NULL); \ - dtime += current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ - printf("%s: (%s:%d) took %lf seconds\n", \ - LOG_MODULE, __XINE_FUNCTION__, __LINE__, dtime); \ - } while(0) -#else -# define XINE_PROFILE(function) function -# define XINE_PROFILE_ACCUMULATE(function) function -#endif /* DEBUG */ - -/** - * get encoding of current locale - */ -char *xine_get_system_encoding(void) XINE_PROTECTED; - -/* - * guess default encoding for the subtitles - */ -const char *xine_guess_spu_encoding(void) XINE_PROTECTED; - -/* - * use the best clock reference (API compatible with gettimeofday) - * note: it will be a monotonic clock, if available. - */ -int xine_monotonic_clock(struct timeval *tv, struct timezone *tz) XINE_PROTECTED; - -/** - * CRC functions - */ -uint32_t _x_compute_crc32 (const uint8_t * data, int32_t length, uint32_t crc32) XINE_PROTECTED; - -/* don't harm following code */ -#ifdef extern -# undef extern -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-utils/xmllexer.h b/src/xine-utils/xmllexer.h deleted file mode 100644 index 10bcc8676..000000000 --- a/src/xine-utils/xmllexer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2002-2003,2007 the xine project - * - * This file is part of xine, a free video player. - * - * The xine-lib XML parser is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The xine-lib XML parser 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth - * Floor, Boston, MA 02110, USA - */ - -/* xml lexer */ -#ifndef XML_LEXER_H -#define XML_LEXER_H - -#ifndef XINE_PROTECTED -#define XINE_PROTECTED -#endif - -/* public constants */ -#define T_ERROR -1 /* lexer error */ -#define T_EOF 0 /* end of file */ -#define T_EOL 1 /* end of line */ -#define T_SEPAR 2 /* separator ' ' '/t' '\n' '\r' */ -#define T_M_START_1 3 /* markup start < */ -#define T_M_START_2 4 /* markup start */ -#define T_M_STOP_2 6 /* markup stop /> */ -#define T_EQUAL 7 /* = */ -#define T_QUOTE 8 /* \" or \' */ -#define T_STRING 9 /* "string" */ -#define T_IDENT 10 /* identifier */ -#define T_DATA 11 /* data */ -#define T_C_START 12 /* */ -#define T_TI_START 14 /* */ -#define T_DOCTYPE_START 16 /* */ -#define T_CDATA_START 18 /* */ - - -/* public functions */ -void lexer_init(const char * buf, int size) XINE_PROTECTED; -int lexer_get_token(char * tok, int tok_size) XINE_PROTECTED; -char *lexer_decode_entities (const char *tok) XINE_PROTECTED; - -#endif diff --git a/src/xine-utils/xmlparser.h b/src/xine-utils/xmlparser.h deleted file mode 100644 index c89cb6dd3..000000000 --- a/src/xine-utils/xmlparser.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2002-2003,2007 the xine project - * - * This file is part of xine, a free video player. - * - * The xine-lib XML parser is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The xine-lib XML parser 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth - * Floor, Boston, MA 02110, USA - */ - -#ifndef XML_PARSER_H -#define XML_PARSER_H - -#ifndef XINE_PROTECTED -#define XINE_PROTECTED -#endif - -/* parser modes */ -#define XML_PARSER_CASE_INSENSITIVE 0 -#define XML_PARSER_CASE_SENSITIVE 1 - -/* return codes */ -#define XML_PARSER_OK 0 -#define XML_PARSER_ERROR 1 - -/* xml_parser_build_tree_with_options flag bits */ -#define XML_PARSER_RELAXED 1 -#define XML_PARSER_MULTI_TEXT 2 - -/* node name for extra text chunks */ -#define CDATA_MARKER "[CDATA]" - -/* xml property */ -typedef struct xml_property_s { - char *name; - char *value; - struct xml_property_s *next; -} xml_property_t; - -/* xml node */ -/* .data contains any text which precedes any subtree elements; - * subtree elements may also contain only text; if so, name is "[CDATA]". - * e.g. bd - * node1: .name="a" .data="b" .child=node2 .next=NULL - * node2: .name="c" .data=NULL .child=NULL .next=node3 - * node3: .name="[CDATA]" .data="d" .child=NULL .next=NULL - * Adjacent text items are merged. - */ -typedef struct xml_node_s { - char *name; - char *data; - struct xml_property_s *props; - struct xml_node_s *child; - struct xml_node_s *next; -} xml_node_t; - -void xml_parser_init(const char * buf, int size, int mode) XINE_PROTECTED; - -int xml_parser_build_tree(xml_node_t **root_node) XINE_PROTECTED; -int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) XINE_PROTECTED; - -void xml_parser_free_tree(xml_node_t *root_node) XINE_PROTECTED; - -const char *xml_parser_get_property (const xml_node_t *node, const char *name) XINE_PROTECTED; -int xml_parser_get_property_int (const xml_node_t *node, const char *name, - int def_value) XINE_PROTECTED; -int xml_parser_get_property_bool (const xml_node_t *node, const char *name, - int def_value) XINE_PROTECTED; - -/* for output: - * returns an escaped string (free() it when done) - * input must be in ASCII or UTF-8 - */ - -typedef enum { - XML_ESCAPE_NO_QUOTE, - XML_ESCAPE_SINGLE_QUOTE, - XML_ESCAPE_DOUBLE_QUOTE -} xml_escape_quote_t; -char *xml_escape_string (const char *s, xml_escape_quote_t quote_type) XINE_PROTECTED; - -/* for debugging purposes: dump read-in xml tree in a nicely - * indented fashion - */ - -void xml_parser_dump_tree (const xml_node_t *node) XINE_PROTECTED; - -#endif -- cgit v1.2.3 From 85b0af8123c0eec0d472c304e3fee440beb7d2b9 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Wed, 19 Dec 2007 01:20:10 +0000 Subject: Add and use new functions for malloc+memcpy(+NUL-term) fragments. --- src/demuxers/demux_real.c | 12 +++--------- src/input/libreal/rmff.c | 30 ++++++++---------------------- src/input/libreal/sdpplin.c | 3 +-- src/xine-utils/utils.c | 13 +++++++++++++ src/xine-utils/xineutils.h | 6 ++++++ 5 files changed, 31 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 962030083..5f1d35d84 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -275,19 +275,13 @@ static mdpr_t *real_parse_mdpr(const char *data) { mdpr->duration=_X_BE_32(&data[28]); mdpr->stream_name_size=data[32]; - mdpr->stream_name=calloc(mdpr->stream_name_size+1, sizeof(char)); - memcpy(mdpr->stream_name, &data[33], mdpr->stream_name_size); - mdpr->stream_name[(int)mdpr->stream_name_size]=0; + mdpr->stream_name=xine_memdup0(&data[33], mdpr->stream_name_size); mdpr->mime_type_size=data[33+mdpr->stream_name_size]; - mdpr->mime_type=calloc(mdpr->mime_type_size+1, sizeof(char)); - memcpy(mdpr->mime_type, &data[34+mdpr->stream_name_size], mdpr->mime_type_size); - mdpr->mime_type[(int)mdpr->mime_type_size]=0; + mdpr->mime_type=xine_memdup0(&data[34+mdpr->stream_name_size], mdpr->mime_type_size); mdpr->type_specific_len=_X_BE_32(&data[34+mdpr->stream_name_size+mdpr->mime_type_size]); - mdpr->type_specific_data=calloc(mdpr->type_specific_len, sizeof(char)); - memcpy(mdpr->type_specific_data, - &data[38+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); + mdpr->type_specific_data=xine_memdup(&data[38+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); lprintf("MDPR: stream number: %i\n", mdpr->stream_number); lprintf("MDPR: maximal bit rate: %i\n", mdpr->max_bit_rate); diff --git a/src/input/libreal/rmff.c b/src/input/libreal/rmff.c index 4fea74636..00f749d43 100644 --- a/src/input/libreal/rmff.c +++ b/src/input/libreal/rmff.c @@ -311,19 +311,13 @@ static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { mdpr->duration=_X_BE_32(&data[36]); mdpr->stream_name_size=data[40]; - mdpr->stream_name = calloc(mdpr->stream_name_size+1, sizeof(char)); - memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size); - mdpr->stream_name[mdpr->stream_name_size]=0; + mdpr->stream_name = xine_memdup0(&data[41], mdpr->stream_name_size); mdpr->mime_type_size=data[41+mdpr->stream_name_size]; - mdpr->mime_type = calloc(mdpr->mime_type_size+1, sizeof(char)); - memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size); - mdpr->mime_type[mdpr->mime_type_size]=0; + mdpr->mime_type = xine_memdup0(&data[42+mdpr->stream_name_size], mdpr->mime_type_size); mdpr->type_specific_len=_X_BE_32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]); - mdpr->type_specific_data = calloc(mdpr->type_specific_len, sizeof(char)); - memcpy(mdpr->type_specific_data, - &data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); + mdpr->type_specific_data = xine_memdup(&data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); return mdpr; } @@ -341,24 +335,17 @@ static rmff_cont_t *rmff_scan_cont(const char *data) { lprintf("warning: unknown object version in CONT: 0x%04x\n", cont->object_version); } cont->title_len=_X_BE_16(&data[10]); - cont->title = calloc((cont->title_len+1), sizeof(char)); - memcpy(cont->title, &data[12], cont->title_len); - cont->title[cont->title_len]=0; + cont->title = xine_memdup0(&data[12], cont->title_len); pos=cont->title_len+12; cont->author_len=_X_BE_16(&data[pos]); - cont->author = calloc(cont->author_len+1, sizeof(char)); - memcpy(cont->author, &data[pos+2], cont->author_len); - cont->author[cont->author_len]=0; + cont->author = xine_memdup0(&data[pos+2], cont->author_len); pos=pos+2+cont->author_len; cont->copyright_len=_X_BE_16(&data[pos]); - cont->copyright = calloc(cont->copyright_len+1, sizeof(char)); - memcpy(cont->copyright, &data[pos+2], cont->copyright_len); + cont->copyright = xine_memdup0(&data[pos+2], cont->copyright_len); cont->copyright[cont->copyright_len]=0; pos=pos+2+cont->copyright_len; cont->comment_len=_X_BE_16(&data[pos]); - cont->comment = calloc(cont->comment_len+1, sizeof(char)); - memcpy(cont->comment, &data[pos+2], cont->comment_len); - cont->comment[cont->comment_len]=0; + cont->comment = xine_memdup0(&data[pos+2], cont->comment_len); return cont; } @@ -584,8 +571,7 @@ rmff_mdpr_t *rmff_new_mdpr( mdpr->mime_type_size=strlen(mime_type); } mdpr->type_specific_len=type_specific_len; - mdpr->type_specific_data = calloc(type_specific_len, sizeof(char)); - memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); + mdpr->type_specific_data = xine_memdup(type_specific_data,type_specific_len); mdpr->mlti_data=NULL; mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c index 5b22e9044..054783119 100644 --- a/src/input/libreal/sdpplin.c +++ b/src/input/libreal/sdpplin.c @@ -199,8 +199,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { if(filter(*data,"a=OpaqueData:buffer;",&buf)) { decoded = b64_decode(buf, decoded, &(desc->mlti_data_size)); if ( decoded != NULL ) { - desc->mlti_data = calloc(desc->mlti_data_size, sizeof(char)); - memcpy(desc->mlti_data, decoded, desc->mlti_data_size); + desc->mlti_data = xine_memdup(decoded, desc->mlti_data_size); handled=1; *data=nl(*data); lprintf("mlti_data_size: %i\n", desc->mlti_data_size); diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c index d9eb7fb3f..e6e997341 100644 --- a/src/xine-utils/utils.c +++ b/src/xine-utils/utils.c @@ -286,6 +286,19 @@ void *xine_xmalloc_aligned(size_t alignment, size_t size, void **base) { return ptr; } +void *xine_memdup (const void *src, size_t length) +{ + void *dst = malloc (length); + return xine_fast_memcpy (dst, src, length); +} + +void *xine_memdup0 (const void *src, size_t length) +{ + char *dst = xine_xmalloc (length + 1); + dst[length] = 0; + return xine_fast_memcpy (dst, src, length); +} + #ifdef WIN32 /* * Parse command line with Windows XP syntax and copy the command (argv[0]). diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h index 4ff87e87c..89c62676b 100644 --- a/src/xine-utils/xineutils.h +++ b/src/xine-utils/xineutils.h @@ -632,6 +632,12 @@ void *xine_xcalloc(size_t nmemb, size_t size) XINE_MALLOC XINE_PROTECTED; */ void *xine_xmalloc_aligned(size_t alignment, size_t size, void **base) XINE_PROTECTED; +/* + * Copy blocks of memory. + */ +void *xine_memdup (const void *src, size_t length) XINE_MALLOC XINE_PROTECTED; +void *xine_memdup0 (const void *src, size_t length) XINE_MALLOC XINE_PROTECTED; + /* * Get user home directory. */ -- cgit v1.2.3 From 75b8595548ee1796fd81e2b5a0a3bc99ee74265d Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Wed, 19 Dec 2007 01:37:07 +0000 Subject: Typo. --- src/input/libreal/real.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c index 29376868c..df604eb10 100644 --- a/src/input/libreal/real.c +++ b/src/input/libreal/real.c @@ -352,7 +352,7 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe calc_response_string (response, buf); /* add tail */ - strcat(response, "01d0a8a3"); + strcat(response, "01d0a8e3"); /* calculate checksum */ resp_len = strlen (response); -- cgit v1.2.3 From 9da4e2dde0da695c240cf48390217ac97cb10c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 02:59:06 +0100 Subject: Update all the code to the new headers layout. --- src/audio_out/audio_alsa_out.c | 8 +++---- src/audio_out/audio_coreaudio_out.c | 6 ++--- src/audio_out/audio_directx2_out.c | 4 ++-- src/audio_out/audio_directx_out.c | 4 ++-- src/audio_out/audio_esd_out.c | 8 +++---- src/audio_out/audio_file_out.c | 6 ++--- src/audio_out/audio_fusionsound_out.c | 6 ++--- src/audio_out/audio_irixal_out.c | 8 +++---- src/audio_out/audio_jack_out.c | 6 ++--- src/audio_out/audio_none_out.c | 6 ++--- src/audio_out/audio_oss_out.c | 8 +++---- src/audio_out/audio_pulse_out.c | 6 ++--- src/audio_out/audio_sun_out.c | 6 ++--- src/combined/flac_decoder.c | 6 ++--- src/combined/flac_demuxer.c | 4 ++-- src/combined/nsf_combined.c | 2 +- src/combined/nsf_decoder.c | 8 +++---- src/combined/nsf_demuxer.c | 8 +++---- src/combined/wavpack_combined.c | 2 +- src/combined/wavpack_decoder.c | 4 ++-- src/combined/wavpack_demuxer.c | 8 +++---- src/combined/xine_ogg_demuxer.c | 6 ++--- src/combined/xine_speex_decoder.c | 6 ++--- src/combined/xine_theora_decoder.c | 10 ++++----- src/combined/xine_vorbis_decoder.c | 6 ++--- src/demuxers/asfheader.c | 2 +- src/demuxers/demux_4xm.c | 8 +++---- src/demuxers/demux_aac.c | 8 +++---- src/demuxers/demux_ac3.c | 8 +++---- src/demuxers/demux_aiff.c | 8 +++---- src/demuxers/demux_asf.c | 8 +++---- src/demuxers/demux_aud.c | 8 +++---- src/demuxers/demux_avi.c | 6 ++--- src/demuxers/demux_cdda.c | 8 +++---- src/demuxers/demux_dts.c | 8 +++---- src/demuxers/demux_eawve.c | 6 ++--- src/demuxers/demux_elem.c | 8 +++---- src/demuxers/demux_film.c | 8 +++---- src/demuxers/demux_flac.c | 8 +++---- src/demuxers/demux_fli.c | 8 +++---- src/demuxers/demux_flv.c | 8 +++---- src/demuxers/demux_idcin.c | 8 +++---- src/demuxers/demux_iff.c | 8 +++---- src/demuxers/demux_image.c | 6 ++--- src/demuxers/demux_ipmovie.c | 8 +++---- src/demuxers/demux_matroska.c | 8 +++---- src/demuxers/demux_mng.c | 6 ++--- src/demuxers/demux_mod.c | 8 +++---- src/demuxers/demux_mpc.c | 8 +++---- src/demuxers/demux_mpeg.c | 6 ++--- src/demuxers/demux_mpeg_block.c | 6 ++--- src/demuxers/demux_mpeg_pes.c | 6 ++--- src/demuxers/demux_mpgaudio.c | 8 +++---- src/demuxers/demux_nsv.c | 10 ++++----- src/demuxers/demux_playlist.c | 6 ++--- src/demuxers/demux_pva.c | 8 +++---- src/demuxers/demux_qt.c | 8 +++---- src/demuxers/demux_rawdv.c | 8 +++---- src/demuxers/demux_real.c | 8 +++---- src/demuxers/demux_realaudio.c | 8 +++---- src/demuxers/demux_roq.c | 8 +++---- src/demuxers/demux_shn.c | 8 +++---- src/demuxers/demux_slave.c | 8 +++---- src/demuxers/demux_smjpeg.c | 8 +++---- src/demuxers/demux_snd.c | 8 +++---- src/demuxers/demux_str.c | 8 +++---- src/demuxers/demux_ts.c | 6 ++--- src/demuxers/demux_tta.c | 10 ++++----- src/demuxers/demux_vmd.c | 8 +++---- src/demuxers/demux_voc.c | 8 +++---- src/demuxers/demux_vox.c | 8 +++---- src/demuxers/demux_vqa.c | 8 +++---- src/demuxers/demux_wav.c | 8 +++---- src/demuxers/demux_wc3movie.c | 8 +++---- src/demuxers/demux_yuv4mpeg2.c | 8 +++---- src/demuxers/demux_yuv_frames.c | 6 ++--- src/demuxers/ebml.c | 4 ++-- src/demuxers/group_audio.c | 4 ++-- src/demuxers/group_audio.h | 2 +- src/demuxers/group_games.c | 4 ++-- src/demuxers/group_games.h | 2 +- src/demuxers/id3.c | 4 ++-- src/demuxers/id3.h | 4 ++-- src/demuxers/matroska.h | 6 ++--- src/dxr3/dxr3.h | 2 +- src/dxr3/dxr3_decode_spu.c | 6 ++--- src/dxr3/dxr3_decode_video.c | 4 ++-- src/dxr3/dxr3_mpeg_encoders.c | 2 +- src/dxr3/dxr3_scr.h | 2 +- src/dxr3/video_out_dxr3.c | 6 ++--- src/dxr3/video_out_dxr3.h | 2 +- src/input/Makefile.am | 1 - src/input/http_helper.c | 2 +- src/input/input_cdda.c | 6 ++--- src/input/input_dvb.c | 6 ++--- src/input/input_dvd.c | 6 ++--- src/input/input_file.c | 8 +++---- src/input/input_gnome_vfs.c | 6 ++--- src/input/input_http.c | 6 ++--- src/input/input_mms.c | 6 ++--- src/input/input_net.c | 6 ++--- src/input/input_pnm.c | 6 ++--- src/input/input_pvr.c | 8 +++---- src/input/input_rtp.c | 6 ++--- src/input/input_rtsp.c | 6 ++--- src/input/input_smb.c | 8 +++---- src/input/input_stdin_fifo.c | 6 ++--- src/input/input_v4l.c | 6 ++--- src/input/input_vcd.c | 6 ++--- src/input/libdvdnav/dvd_reader.c | 2 +- src/input/libreal/asmrp.c | 2 +- src/input/libreal/real.c | 4 ++-- src/input/libreal/rmff.c | 2 +- src/input/libreal/sdpplin.c | 2 +- src/input/librtsp/rtsp.c | 4 ++-- src/input/librtsp/rtsp.h | 2 +- src/input/librtsp/rtsp_session.c | 2 +- src/input/media_helper.h | 2 +- src/input/mms.c | 4 ++-- src/input/mms.h | 2 +- src/input/mmsh.c | 4 ++-- src/input/mmsh.h | 2 +- src/input/net_buf_ctrl.h | 2 +- src/input/pnm.c | 6 ++--- src/input/pnm.h | 2 +- src/input/vcd/xine-extra.h | 4 ++-- src/input/vcd/xineplug_inp_vcd.c | 4 ++-- src/libffmpeg/ff_audio_decoder.c | 6 ++--- src/libffmpeg/ff_dvaudio_decoder.c | 6 ++--- src/libffmpeg/ff_mpeg_parser.h | 2 +- src/libffmpeg/ff_video_decoder.c | 6 ++--- src/libffmpeg/ffmpeg_decoder.c | 2 +- src/libmpeg2/cpu_state.c | 2 +- src/libmpeg2/decode.c | 6 ++--- src/libmpeg2/header.c | 2 +- src/libmpeg2/idct.c | 2 +- src/libmpeg2/idct_altivec.c | 2 +- src/libmpeg2/idct_mmx.c | 2 +- src/libmpeg2/libmpeg2_accel.c | 2 +- src/libmpeg2/motion_comp.c | 2 +- src/libmpeg2/motion_comp_mmx.c | 2 +- src/libmpeg2/mpeg2_internal.h | 2 +- src/libmpeg2/slice.c | 6 ++--- src/libmpeg2/slice_xvmc.c | 8 +++---- src/libmpeg2/slice_xvmc_vld.c | 4 ++-- src/libmpeg2/xine_mpeg2_decoder.c | 6 ++--- src/libmpeg2new/libmpeg2/idct_alpha.c | 2 +- src/libmpeg2new/libmpeg2/idct_altivec.c | 2 +- src/libmpeg2new/libmpeg2/motion_comp_alpha.c | 2 +- src/libmpeg2new/libmpeg2/motion_comp_altivec.c | 2 +- src/libmpeg2new/libmpeg2/motion_comp_vis.c | 2 +- src/libmpeg2new/libmpeg2/rgb.c | 2 +- src/libmpeg2new/libmpeg2/rgb_mmx.c | 2 +- src/libmpeg2new/libmpeg2/rgb_vis.c | 2 +- src/libmpeg2new/xine_mpeg2new_decoder.c | 6 ++--- src/libreal/real_common.h | 2 +- src/libreal/xine_real_audio_decoder.c | 8 +++---- src/libreal/xine_real_video_decoder.c | 8 +++---- src/libspucc/cc_decoder.c | 10 ++++----- src/libspucc/xine_cc_decoder.c | 6 ++--- src/libspucmml/xine_cmml_decoder.c | 2 +- src/libspudec/spu.c | 6 ++--- src/libspudec/spu.h | 4 ++-- src/libspudec/xine_spu_decoder.c | 6 ++--- src/libspudvb/xine_spudvb_decoder.c | 6 ++--- src/libsputext/demux_sputext.c | 6 ++--- src/libsputext/xine_sputext_decoder.c | 8 +++---- src/libw32dll/qt_decoder.c | 6 ++--- src/libw32dll/w32codec.c | 10 ++++----- src/libw32dll/wine/registry.c | 2 +- src/libw32dll/wine/win32.c | 2 +- src/libxineadec/fooaudio.c | 8 +++---- src/libxineadec/gsm610.c | 8 +++---- src/libxineadec/xine_a52_decoder.c | 8 +++---- src/libxineadec/xine_dts_decoder.c | 8 +++---- src/libxineadec/xine_faad_decoder.c | 8 +++---- src/libxineadec/xine_lpcm_decoder.c | 6 ++--- src/libxineadec/xine_mad_decoder.c | 8 +++---- src/libxineadec/xine_musepack_decoder.c | 8 +++---- src/libxinevdec/bitplane.c | 8 +++---- src/libxinevdec/foovideo.c | 8 +++---- src/libxinevdec/gdkpixbuf.c | 8 +++---- src/libxinevdec/image.c | 8 +++---- src/libxinevdec/rgb.c | 8 +++---- src/libxinevdec/yuv.c | 8 +++---- src/post/audio/audio_filters.c | 6 ++--- src/post/audio/audio_filters.h | 2 +- src/post/audio/stretch.c | 8 +++---- src/post/audio/upmix.c | 6 ++--- src/post/audio/upmix_mono.c | 4 ++-- src/post/audio/volnorm.c | 6 ++--- src/post/deinterlace/deinterlace.c | 2 +- src/post/deinterlace/plugins/greedy.c | 4 ++-- src/post/deinterlace/plugins/greedy2frame.c | 4 ++-- src/post/deinterlace/plugins/kdetv_greedyh.c | 4 ++-- src/post/deinterlace/plugins/kdetv_tomsmocomp.c | 4 ++-- src/post/deinterlace/plugins/linearblend.c | 4 ++-- src/post/deinterlace/plugins/vfir.c | 4 ++-- src/post/deinterlace/speedy.c | 4 ++-- src/post/deinterlace/xine_plugin.c | 8 +++---- src/post/goom/goom_core.c | 2 +- src/post/goom/mmx.h | 2 +- src/post/goom/xine_goom.c | 6 ++--- src/post/mosaico/mosaico.c | 4 ++-- src/post/mosaico/switch.c | 4 ++-- src/post/planar/boxblur.c | 6 ++--- src/post/planar/denoise3d.c | 6 ++--- src/post/planar/eq.c | 6 ++--- src/post/planar/eq2.c | 6 ++--- src/post/planar/expand.c | 4 ++-- src/post/planar/fill.c | 4 ++-- src/post/planar/invert.c | 4 ++-- src/post/planar/noise.c | 6 ++--- src/post/planar/planar.c | 6 ++--- src/post/planar/pp.c | 6 ++--- src/post/planar/unsharp.c | 6 ++--- src/post/visualizations/fftgraph.c | 6 ++--- src/post/visualizations/fftscope.c | 6 ++--- src/post/visualizations/fooviz.c | 6 ++--- src/post/visualizations/oscope.c | 6 ++--- src/post/visualizations/visualizations.c | 4 ++-- src/post/visualizations/visualizations.h | 2 +- src/vdr/input_vdr.c | 6 ++--- src/vdr/post_vdr.c | 4 ++-- src/vdr/post_vdr_audio.c | 4 ++-- src/vdr/post_vdr_video.c | 4 ++-- src/video_out/macosx/XineOpenGLView.m | 6 +---- src/video_out/video_out_aa.c | 6 ++--- src/video_out/video_out_caca.c | 6 ++--- src/video_out/video_out_directfb.c | 8 +++---- src/video_out/video_out_directx.c | 6 ++--- src/video_out/video_out_fb.c | 8 +++---- src/video_out/video_out_none.c | 8 +++---- src/video_out/video_out_opengl.c | 6 ++--- src/video_out/video_out_pgx32.c | 6 ++--- src/video_out/video_out_pgx64.c | 6 ++--- src/video_out/video_out_sdl.c | 8 +++---- src/video_out/video_out_stk.c | 8 +++---- src/video_out/video_out_syncfb.c | 8 +++---- src/video_out/video_out_vidix.c | 8 +++---- src/video_out/video_out_xcbshm.c | 8 +++---- src/video_out/video_out_xcbxv.c | 8 +++---- src/video_out/video_out_xshm.c | 8 +++---- src/video_out/video_out_xv.c | 8 +++---- src/video_out/video_out_xvmc.c | 8 +++---- src/video_out/x11osd.c | 2 +- src/video_out/x11osd.h | 2 +- src/video_out/xcbosd.c | 2 +- src/video_out/xcbosd.h | 2 +- src/video_out/xxmc.h | 6 ++--- src/video_out/yuv2rgb.c | 2 +- src/video_out/yuv2rgb_mlib.c | 4 ++-- src/video_out/yuv2rgb_mmx.c | 2 +- src/xine-engine/alphablend.c | 6 ++--- src/xine-engine/audio_decoder.c | 4 ++-- src/xine-engine/audio_out.c | 10 ++++----- src/xine-engine/broadcaster.c | 6 ++--- src/xine-engine/buffer.c | 6 ++--- src/xine-engine/buffer_types.c | 2 +- src/xine-engine/configfile.c | 6 ++--- src/xine-engine/demux.c | 6 ++--- src/xine-engine/events.c | 2 +- src/xine-engine/info_helper.c | 2 +- src/xine-engine/input_cache.c | 2 +- src/xine-engine/input_rip.c | 2 +- src/xine-engine/io_helper.c | 2 +- src/xine-engine/load_plugins.c | 22 +++++++++--------- src/xine-engine/lrb.c | 2 +- src/xine-engine/lrb.h | 6 +---- src/xine-engine/metronom.c | 6 ++--- src/xine-engine/osd.c | 8 +++---- src/xine-engine/post.c | 2 +- src/xine-engine/refcounter.c | 4 ++-- src/xine-engine/resample.c | 4 ++-- src/xine-engine/scratch.c | 4 ++-- src/xine-engine/spu.c | 4 ++-- src/xine-engine/video_decoder.c | 4 ++-- src/xine-engine/video_out.c | 8 +++---- src/xine-engine/video_overlay.c | 8 +++---- src/xine-engine/vo_scale.c | 4 ++-- src/xine-engine/xine.c | 30 ++++++++++++------------- src/xine-engine/xine_interface.c | 10 ++++----- src/xine-utils/array.c | 4 ++-- src/xine-utils/color.c | 2 +- src/xine-utils/copy.c | 2 +- src/xine-utils/cpu_accel.c | 2 +- src/xine-utils/crc.c | 2 +- src/xine-utils/list.c | 4 ++-- src/xine-utils/memcpy.c | 2 +- src/xine-utils/monitor.c | 2 +- src/xine-utils/pool.c | 6 ++--- src/xine-utils/ring_buffer.c | 8 +++---- src/xine-utils/sorted_array.c | 4 ++-- src/xine-utils/utils.c | 6 ++--- src/xine-utils/xine_buffer.c | 2 +- src/xine-utils/xine_check.c | 2 +- src/xine-utils/xine_check.h | 6 +---- src/xine-utils/xine_mutex.c | 2 +- src/xine-utils/xmllexer.c | 4 ++-- src/xine-utils/xmlparser.c | 6 ++--- 300 files changed, 817 insertions(+), 830 deletions(-) (limited to 'src') diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c index 40dc7ffed..a6f81cb35 100644 --- a/src/audio_out/audio_alsa_out.c +++ b/src/audio_out/audio_alsa_out.c @@ -50,10 +50,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "audio_out.h" +#include +#include +#include +#include /* #define ALSA_LOG diff --git a/src/audio_out/audio_coreaudio_out.c b/src/audio_out/audio_coreaudio_out.c index 551810e3e..001d873fa 100644 --- a/src/audio_out/audio_coreaudio_out.c +++ b/src/audio_out/audio_coreaudio_out.c @@ -41,9 +41,9 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" +#include +#include +#include #include #include diff --git a/src/audio_out/audio_directx2_out.c b/src/audio_out/audio_directx2_out.c index 9bcc52233..309edf961 100644 --- a/src/audio_out/audio_directx2_out.c +++ b/src/audio_out/audio_directx2_out.c @@ -58,8 +58,8 @@ #define LOG */ -#include "xine_internal.h" -#include "audio_out.h" +#include +#include #define AO_OUT_DIRECTX2_IFACE_VERSION 9 diff --git a/src/audio_out/audio_directx_out.c b/src/audio_out/audio_directx_out.c index c7dea4e04..5d16698b2 100644 --- a/src/audio_out/audio_directx_out.c +++ b/src/audio_out/audio_directx_out.c @@ -38,8 +38,8 @@ typedef unsigned char boolean; #define LOG */ -#include "audio_out.h" -#include "xine_internal.h" +#include +#include #define MAX_CHANNELS 6 diff --git a/src/audio_out/audio_esd_out.c b/src/audio_out/audio_esd_out.c index 9aec15c7a..81017f1ca 100644 --- a/src/audio_out/audio_esd_out.c +++ b/src/audio_out/audio_esd_out.c @@ -33,10 +33,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" -#include "metronom.h" +#include +#include +#include +#include #define AO_OUT_ESD_IFACE_VERSION 9 diff --git a/src/audio_out/audio_file_out.c b/src/audio_out/audio_file_out.c index fda5ec7df..b75e6777b 100644 --- a/src/audio_out/audio_file_out.c +++ b/src/audio_out/audio_file_out.c @@ -31,9 +31,9 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" +#include +#include +#include #include "bswap.h" #define AO_OUT_FILE_IFACE_VERSION 9 diff --git a/src/audio_out/audio_fusionsound_out.c b/src/audio_out/audio_fusionsound_out.c index ceda0a293..a79d21213 100644 --- a/src/audio_out/audio_fusionsound_out.c +++ b/src/audio_out/audio_fusionsound_out.c @@ -34,9 +34,9 @@ #define LOG_VERBOSE #include "xine.h" -#include "xine_internal.h" -#include "audio_out.h" -#include "xineutils.h" +#include +#include +#include #include diff --git a/src/audio_out/audio_irixal_out.c b/src/audio_out/audio_irixal_out.c index 1654cc1a7..e86b78e76 100644 --- a/src/audio_out/audio_irixal_out.c +++ b/src/audio_out/audio_irixal_out.c @@ -37,10 +37,10 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "audio_out.h" +#include +#include +#include +#include //#ifndef AFMT_S16_NE //# if defined(sparc) || defined(__sparc__) || defined(PPC) diff --git a/src/audio_out/audio_jack_out.c b/src/audio_out/audio_jack_out.c index b3b2d4a19..7b8bb3eb3 100644 --- a/src/audio_out/audio_jack_out.c +++ b/src/audio_out/audio_jack_out.c @@ -8,9 +8,9 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" +#include +#include +#include #include diff --git a/src/audio_out/audio_none_out.c b/src/audio_out/audio_none_out.c index 0e5cf1864..fa6547880 100644 --- a/src/audio_out/audio_none_out.c +++ b/src/audio_out/audio_none_out.c @@ -31,9 +31,9 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" +#include +#include +#include #define AO_OUT_NONE_IFACE_VERSION 9 diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c index 5b4faada5..8e0e52fd7 100644 --- a/src/audio_out/audio_oss_out.c +++ b/src/audio_out/audio_oss_out.c @@ -64,10 +64,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "audio_out.h" +#include +#include +#include +#include #include diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 6054e137e..b4ec0b156 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -41,9 +41,9 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" +#include +#include +#include #include "bswap.h" #define GAP_TOLERANCE AO_MAX_GAP diff --git a/src/audio_out/audio_sun_out.c b/src/audio_out/audio_sun_out.c index c37397639..921e5fd15 100644 --- a/src/audio_out/audio_sun_out.c +++ b/src/audio_out/audio_sun_out.c @@ -45,9 +45,9 @@ typedef unsigned uint_t; #endif -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" +#include +#include +#include #ifdef __svr4__ #define CS4231_WORKAROUND 1 /* enable workaround for audiocs play.samples bug */ diff --git a/src/combined/flac_decoder.c b/src/combined/flac_decoder.c index 9ec024d71..40c5fa6a3 100644 --- a/src/combined/flac_decoder.c +++ b/src/combined/flac_decoder.c @@ -44,9 +44,9 @@ #define LOG */ -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" +#include +#include +#include typedef struct { audio_decoder_class_t decoder_class; diff --git a/src/combined/flac_demuxer.c b/src/combined/flac_demuxer.c index bee98d2a3..1f390a86f 100644 --- a/src/combined/flac_demuxer.c +++ b/src/combined/flac_demuxer.c @@ -51,8 +51,8 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "../demuxers/demux.h" #ifndef LEGACY_FLAC diff --git a/src/combined/nsf_combined.c b/src/combined/nsf_combined.c index 085467937..18ab05863 100644 --- a/src/combined/nsf_combined.c +++ b/src/combined/nsf_combined.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ -#include "xine_internal.h" +#include #include "nsf_combined.h" static const demuxer_info_t demux_info_nsf = { diff --git a/src/combined/nsf_decoder.c b/src/combined/nsf_decoder.c index b2694e789..cb3b6e7b0 100644 --- a/src/combined/nsf_decoder.c +++ b/src/combined/nsf_decoder.c @@ -27,10 +27,10 @@ #include #include -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" /* Nosefart includes */ diff --git a/src/combined/nsf_demuxer.c b/src/combined/nsf_demuxer.c index cce7c8983..451e6e938 100644 --- a/src/combined/nsf_demuxer.c +++ b/src/combined/nsf_demuxer.c @@ -46,10 +46,10 @@ /* #define LOG_VERBOSE */ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "nsf_combined.h" diff --git a/src/combined/wavpack_combined.c b/src/combined/wavpack_combined.c index 9c5dade03..edf4bec01 100644 --- a/src/combined/wavpack_combined.c +++ b/src/combined/wavpack_combined.c @@ -20,7 +20,7 @@ * xine interface to libwavpack by Diego Pettenò */ -#include "xine_internal.h" +#include #include "wavpack_combined.h" static const demuxer_info_t demux_info_wv = { diff --git a/src/combined/wavpack_decoder.c b/src/combined/wavpack_decoder.c index 8eb041664..80a14e678 100644 --- a/src/combined/wavpack_decoder.c +++ b/src/combined/wavpack_decoder.c @@ -27,8 +27,8 @@ #define LOG_MODULE "decode_wavpack" #define LOG_VERBOSE -#include "xine_internal.h" -#include "attributes.h" +#include +#include #include "bswap.h" #include diff --git a/src/combined/wavpack_demuxer.c b/src/combined/wavpack_demuxer.c index 310f4cecb..9c0831cfa 100644 --- a/src/combined/wavpack_demuxer.c +++ b/src/combined/wavpack_demuxer.c @@ -28,11 +28,11 @@ #define LOG_VERBOSE #define LOG -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #include "bswap.h" -#include "attributes.h" +#include #include #include "wavpack_combined.h" diff --git a/src/combined/xine_ogg_demuxer.c b/src/combined/xine_ogg_demuxer.c index ea03b5eec..8c722f84f 100644 --- a/src/combined/xine_ogg_demuxer.c +++ b/src/combined/xine_ogg_demuxer.c @@ -65,9 +65,9 @@ #define DEBUG_PTS 0 #define DEBUG_VIDEO_PACKETS 0 -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #include "bswap.h" #include "flacutils.h" diff --git a/src/combined/xine_speex_decoder.c b/src/combined/xine_speex_decoder.c index e4fc44eec..a94ab0c0e 100644 --- a/src/combined/xine_speex_decoder.c +++ b/src/combined/xine_speex_decoder.c @@ -34,9 +34,9 @@ */ #define LOG_BUFFERS 0 -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" +#include +#include +#include #include diff --git a/src/combined/xine_theora_decoder.c b/src/combined/xine_theora_decoder.c index 8d06a5510..262cb5414 100644 --- a/src/combined/xine_theora_decoder.c +++ b/src/combined/xine_theora_decoder.c @@ -39,11 +39,11 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "metronom.h" -#include "xineutils.h" +#include +#include +#include +#include +#include typedef struct theora_class_s { video_decoder_class_t decoder_class; diff --git a/src/combined/xine_vorbis_decoder.c b/src/combined/xine_vorbis_decoder.c index aa3546e2e..143c761c4 100644 --- a/src/combined/xine_vorbis_decoder.c +++ b/src/combined/xine_vorbis_decoder.c @@ -33,9 +33,9 @@ #define LOG */ -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" +#include +#include +#include #include #include diff --git a/src/demuxers/asfheader.c b/src/demuxers/asfheader.c index 23692574e..97537c337 100644 --- a/src/demuxers/asfheader.c +++ b/src/demuxers/asfheader.c @@ -17,7 +17,7 @@ #define LOG */ -#include "xineutils.h" +#include #include "bswap.h" #include "asfheader.h" diff --git a/src/demuxers/demux_4xm.c b/src/demuxers/demux_4xm.c index 5ad5d5938..6256cb042 100644 --- a/src/demuxers/demux_4xm.c +++ b/src/demuxers/demux_4xm.c @@ -40,10 +40,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c index 3edd0bca4..0b02f1d99 100644 --- a/src/demuxers/demux_aac.c +++ b/src/demuxers/demux_aac.c @@ -39,10 +39,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_ac3.c b/src/demuxers/demux_ac3.c index e48416803..2ccd5217e 100644 --- a/src/demuxers/demux_ac3.c +++ b/src/demuxers/demux_ac3.c @@ -44,10 +44,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index f873f5d4f..d3b19701a 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -33,10 +33,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index f5091035b..156a78d6c 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -45,12 +45,12 @@ /* #define LOG */ -#include "xine_internal.h" -#include "demux.h" -#include "xineutils.h" +#include +#include +#include #include "bswap.h" #include "asfheader.h" -#include "xmlparser.h" +#include #define CODEC_TYPE_AUDIO 0 #define CODEC_TYPE_VIDEO 1 diff --git a/src/demuxers/demux_aud.c b/src/demuxers/demux_aud.c index 2aa83d162..c58500ab2 100644 --- a/src/demuxers/demux_aud.c +++ b/src/demuxers/demux_aud.c @@ -45,10 +45,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index d2e0c0412..ecc71b649 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -70,9 +70,9 @@ #define DEBUG_ODML #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #include "bswap.h" /* diff --git a/src/demuxers/demux_cdda.c b/src/demuxers/demux_cdda.c index d2a2b4db4..03dcc2605 100644 --- a/src/demuxers/demux_cdda.c +++ b/src/demuxers/demux_cdda.c @@ -41,10 +41,10 @@ /* #define LOG_VERBOSE */ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_dts.c b/src/demuxers/demux_dts.c index be552653f..9d3313a72 100644 --- a/src/demuxers/demux_dts.c +++ b/src/demuxers/demux_dts.c @@ -40,10 +40,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_eawve.c b/src/demuxers/demux_eawve.c index b0d10dc1c..04cc714d7 100644 --- a/src/demuxers/demux_eawve.c +++ b/src/demuxers/demux_eawve.c @@ -39,10 +39,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" -#include "demux.h" +#include #include "group_games.h" #define FOURCC_TAG BE_FOURCC diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c index a40d3053e..e653818c4 100644 --- a/src/demuxers/demux_elem.c +++ b/src/demuxers/demux_elem.c @@ -38,10 +38,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #define NUM_PREVIEW_BUFFERS 50 #define SCRATCH_SIZE 256 diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c index d09f8f4f1..cc9e90d66 100644 --- a/src/demuxers/demux_film.c +++ b/src/demuxers/demux_film.c @@ -47,10 +47,10 @@ * demuxer is dispatching to the engine */ #define DEBUG_FILM_DEMUX 0 -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c index 0380de846..b4c5427c5 100644 --- a/src/demuxers/demux_flac.c +++ b/src/demuxers/demux_flac.c @@ -40,10 +40,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c index 2da3019b2..0dad5883a 100644 --- a/src/demuxers/demux_fli.c +++ b/src/demuxers/demux_fli.c @@ -35,10 +35,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #define FLI_HEADER_SIZE 128 diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c index 7f9dec5fe..86f9a038b 100644 --- a/src/demuxers/demux_flv.c +++ b/src/demuxers/demux_flv.c @@ -42,10 +42,10 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_idcin.c b/src/demuxers/demux_idcin.c index 39b38c81d..695470415 100644 --- a/src/demuxers/demux_idcin.c +++ b/src/demuxers/demux_idcin.c @@ -83,10 +83,10 @@ * demuxer is dispatching to the engine */ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_iff.c b/src/demuxers/demux_iff.c index 9e91684d5..665d29cd2 100644 --- a/src/demuxers/demux_iff.c +++ b/src/demuxers/demux_iff.c @@ -47,10 +47,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "iff.h" diff --git a/src/demuxers/demux_image.c b/src/demuxers/demux_image.c index 4731acfe4..cb6f8c8fe 100644 --- a/src/demuxers/demux_image.c +++ b/src/demuxers/demux_image.c @@ -38,10 +38,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" -#include "demux.h" +#include #define IMAGE_HEADER_LEN 4 diff --git a/src/demuxers/demux_ipmovie.c b/src/demuxers/demux_ipmovie.c index cc71da6d4..4d08af6fa 100644 --- a/src/demuxers/demux_ipmovie.c +++ b/src/demuxers/demux_ipmovie.c @@ -40,10 +40,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c index 16cf87978..e976e7d63 100644 --- a/src/demuxers/demux_matroska.c +++ b/src/demuxers/demux_matroska.c @@ -42,10 +42,10 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "ebml.h" diff --git a/src/demuxers/demux_mng.c b/src/demuxers/demux_mng.c index f7af7ec42..18c4b1b57 100644 --- a/src/demuxers/demux_mng.c +++ b/src/demuxers/demux_mng.c @@ -46,9 +46,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include typedef struct { demux_plugin_t demux_plugin; diff --git a/src/demuxers/demux_mod.c b/src/demuxers/demux_mod.c index 54dacdc8e..17e744b94 100644 --- a/src/demuxers/demux_mod.c +++ b/src/demuxers/demux_mod.c @@ -42,10 +42,10 @@ /* #define LOG_VERBOSE */ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "modplug.h" #include "bswap.h" diff --git a/src/demuxers/demux_mpc.c b/src/demuxers/demux_mpc.c index 60750b550..6a4cfb285 100644 --- a/src/demuxers/demux_mpc.c +++ b/src/demuxers/demux_mpc.c @@ -41,10 +41,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c index 0a97b27bc..8c339fd88 100644 --- a/src/demuxers/demux_mpeg.c +++ b/src/demuxers/demux_mpeg.c @@ -39,9 +39,9 @@ #define LOG */ -#include "xine_internal.h" -#include "demux.h" -#include "xineutils.h" +#include +#include +#include #define NUM_PREVIEW_BUFFERS 150 #define SCRATCH_SIZE 256 diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index 91b69328c..b46008b94 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.c @@ -37,9 +37,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #define NUM_PREVIEW_BUFFERS 250 #define DISC_TRESHOLD 90000 diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c index d47c1ed01..f5d554020 100644 --- a/src/demuxers/demux_mpeg_pes.c +++ b/src/demuxers/demux_mpeg_pes.c @@ -41,9 +41,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #define NUM_PREVIEW_BUFFERS 250 #define DISC_TRESHOLD 90000 diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c index 1648be926..39d537a4c 100644 --- a/src/demuxers/demux_mpgaudio.c +++ b/src/demuxers/demux_mpgaudio.c @@ -38,10 +38,10 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "compat.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" #include "id3.h" diff --git a/src/demuxers/demux_nsv.c b/src/demuxers/demux_nsv.c index d5ffed5f8..74f98c7cd 100644 --- a/src/demuxers/demux_nsv.c +++ b/src/demuxers/demux_nsv.c @@ -40,12 +40,12 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" -#include "buffer.h" +#include #define FOURCC_TAG BE_FOURCC #define NSVf_TAG FOURCC_TAG('N', 'S', 'V', 'f') diff --git a/src/demuxers/demux_playlist.c b/src/demuxers/demux_playlist.c index c6df006fe..3dd689657 100644 --- a/src/demuxers/demux_playlist.c +++ b/src/demuxers/demux_playlist.c @@ -40,10 +40,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" -#include "demux.h" +#include typedef enum { XINE_PLT_NONE = 0, diff --git a/src/demuxers/demux_pva.c b/src/demuxers/demux_pva.c index 2f85387b2..9987da057 100644 --- a/src/demuxers/demux_pva.c +++ b/src/demuxers/demux_pva.c @@ -39,10 +39,10 @@ /* #define LOG_VERBOSE */ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #define PVA_PREAMBLE_SIZE 8 diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 8fb554de2..a54bc4e73 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -43,10 +43,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "qtpalette.h" diff --git a/src/demuxers/demux_rawdv.c b/src/demuxers/demux_rawdv.c index 0ae52b6bf..10b3170e6 100644 --- a/src/demuxers/demux_rawdv.c +++ b/src/demuxers/demux_rawdv.c @@ -32,10 +32,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #define NTSC_FRAME_SIZE 120000 #define NTSC_FRAME_RATE 29.97 diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 962030083..c14be6b47 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -49,10 +49,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #define FOURCC_TAG BE_FOURCC diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c index 0ce399e11..732ddfcc4 100644 --- a/src/demuxers/demux_realaudio.c +++ b/src/demuxers/demux_realaudio.c @@ -34,10 +34,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_roq.c b/src/demuxers/demux_roq.c index 95f81de9a..83e589be0 100644 --- a/src/demuxers/demux_roq.c +++ b/src/demuxers/demux_roq.c @@ -40,10 +40,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_shn.c b/src/demuxers/demux_shn.c index 445661b8f..d5e46f873 100644 --- a/src/demuxers/demux_shn.c +++ b/src/demuxers/demux_shn.c @@ -35,10 +35,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_slave.c b/src/demuxers/demux_slave.c index fc42ae4c4..80a5ebbf8 100644 --- a/src/demuxers/demux_slave.c +++ b/src/demuxers/demux_slave.c @@ -42,10 +42,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #define SCRATCH_SIZE 1024 #define CHECK_VPTS_INTERVAL 2*90000 diff --git a/src/demuxers/demux_smjpeg.c b/src/demuxers/demux_smjpeg.c index d24459f5b..10cdf8120 100644 --- a/src/demuxers/demux_smjpeg.c +++ b/src/demuxers/demux_smjpeg.c @@ -39,10 +39,10 @@ /* #define LOG_VERBOSE */ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_snd.c b/src/demuxers/demux_snd.c index 728caf170..d7bdd0839 100644 --- a/src/demuxers/demux_snd.c +++ b/src/demuxers/demux_snd.c @@ -33,10 +33,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_str.c b/src/demuxers/demux_str.c index ccb653ad2..f125f09c5 100644 --- a/src/demuxers/demux_str.c +++ b/src/demuxers/demux_str.c @@ -123,10 +123,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 5b671f3c4..e80e8af70 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -147,9 +147,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include /* #define TS_LOG diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index 2a8af09bb..2d35a60e8 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -24,13 +24,13 @@ #define LOG_MODULE "demux_tta" #define LOG_VERBOSE -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" -#include "attributes.h" +#include typedef struct { demux_plugin_t demux_plugin; diff --git a/src/demuxers/demux_vmd.c b/src/demuxers/demux_vmd.c index 41475f966..c2902eac1 100644 --- a/src/demuxers/demux_vmd.c +++ b/src/demuxers/demux_vmd.c @@ -45,10 +45,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_voc.c b/src/demuxers/demux_voc.c index ffd904a6f..ce42d61d8 100644 --- a/src/demuxers/demux_voc.c +++ b/src/demuxers/demux_voc.c @@ -37,10 +37,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_vox.c b/src/demuxers/demux_vox.c index 0e648263e..306f2414f 100644 --- a/src/demuxers/demux_vox.c +++ b/src/demuxers/demux_vox.c @@ -34,10 +34,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_vqa.c b/src/demuxers/demux_vqa.c index 3cbbced9d..3acd56bc1 100644 --- a/src/demuxers/demux_vqa.c +++ b/src/demuxers/demux_vqa.c @@ -40,10 +40,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c index 9cf2adefe..b8f0d0194 100644 --- a/src/demuxers/demux_wav.c +++ b/src/demuxers/demux_wav.c @@ -34,10 +34,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" #include "group_audio.h" diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c index b3cf9dfb3..bb9a40306 100644 --- a/src/demuxers/demux_wc3movie.c +++ b/src/demuxers/demux_wc3movie.c @@ -42,10 +42,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #include "group_games.h" diff --git a/src/demuxers/demux_yuv4mpeg2.c b/src/demuxers/demux_yuv4mpeg2.c index 54e8ebbaa..a0bf31bce 100644 --- a/src/demuxers/demux_yuv4mpeg2.c +++ b/src/demuxers/demux_yuv4mpeg2.c @@ -36,10 +36,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "demux.h" +#include +#include +#include +#include #include "bswap.h" #define Y4M_SIGNATURE_SIZE 9 diff --git a/src/demuxers/demux_yuv_frames.c b/src/demuxers/demux_yuv_frames.c index 301a5978e..0cef51f60 100644 --- a/src/demuxers/demux_yuv_frames.c +++ b/src/demuxers/demux_yuv_frames.c @@ -39,9 +39,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #define WRAP_THRESHOLD 20000 diff --git a/src/demuxers/ebml.c b/src/demuxers/ebml.c index d5f7bb9b5..772b848eb 100644 --- a/src/demuxers/ebml.c +++ b/src/demuxers/ebml.c @@ -31,8 +31,8 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" #include "ebml.h" diff --git a/src/demuxers/group_audio.c b/src/demuxers/group_audio.c index d3832c36d..250eeefb4 100644 --- a/src/demuxers/group_audio.c +++ b/src/demuxers/group_audio.c @@ -24,8 +24,8 @@ #include "config.h" #endif -#include "xine_internal.h" -#include "demux.h" +#include +#include #include "group_audio.h" diff --git a/src/demuxers/group_audio.h b/src/demuxers/group_audio.h index 11aac35d7..394cad2a3 100644 --- a/src/demuxers/group_audio.h +++ b/src/demuxers/group_audio.h @@ -21,7 +21,7 @@ #ifndef HAVE_GROUP_AUDIO_H #define HAVE_GROUP_AUDIO_H -#include "xine_internal.h" +#include void *demux_aac_init_plugin (xine_t *xine, void *data); void *demux_ac3_init_plugin (xine_t *xine, void *data); diff --git a/src/demuxers/group_games.c b/src/demuxers/group_games.c index cfae26848..2d01b726e 100644 --- a/src/demuxers/group_games.c +++ b/src/demuxers/group_games.c @@ -24,8 +24,8 @@ #include "config.h" #endif -#include "xine_internal.h" -#include "demux.h" +#include +#include #include "group_games.h" diff --git a/src/demuxers/group_games.h b/src/demuxers/group_games.h index f93d4bb07..352ec5524 100644 --- a/src/demuxers/group_games.h +++ b/src/demuxers/group_games.h @@ -21,7 +21,7 @@ #ifndef HAVE_GROUP_GAMES_H #define HAVE_GROUP_GAMES_H -#include "xine_internal.h" +#include void *demux_eawve_init_plugin(xine_t *xine, void *data); void *demux_idcin_init_plugin (xine_t *xine, void *data); diff --git a/src/demuxers/id3.c b/src/demuxers/id3.c index ceb66014f..b9bb75744 100644 --- a/src/demuxers/id3.c +++ b/src/demuxers/id3.c @@ -40,8 +40,8 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" #include "id3.h" diff --git a/src/demuxers/id3.h b/src/demuxers/id3.h index 29285bf7a..542a17bc4 100644 --- a/src/demuxers/id3.h +++ b/src/demuxers/id3.h @@ -25,8 +25,8 @@ #ifndef ID3_H #define ID3_H -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" /* id3v2 */ diff --git a/src/demuxers/matroska.h b/src/demuxers/matroska.h index 6806c207d..215c63dd0 100644 --- a/src/demuxers/matroska.h +++ b/src/demuxers/matroska.h @@ -20,9 +20,9 @@ #ifndef MATROSKA_H #define MATROSKA_H -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" +#include +#include +#include #include "ebml.h" diff --git a/src/dxr3/dxr3.h b/src/dxr3/dxr3.h index f08ddcd04..0b0961ca0 100644 --- a/src/dxr3/dxr3.h +++ b/src/dxr3/dxr3.h @@ -23,7 +23,7 @@ #include "em8300.h" -#include "xine_internal.h" +#include /* data for the device name config entry */ #define CONF_KEY "dxr3.device_number" diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c index 7c501e9d8..8280d4714 100644 --- a/src/dxr3/dxr3_decode_spu.c +++ b/src/dxr3/dxr3_decode_spu.c @@ -42,9 +42,9 @@ #define LOG_SPU 0 #define LOG_BTN 0 -#include "xine_internal.h" -#include "xineutils.h" -#include "buffer.h" +#include +#include +#include #include "xine-engine/bswap.h" #ifdef HAVE_DVDNAV # include diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c index e26e303a1..39da80249 100644 --- a/src/dxr3/dxr3_decode_video.c +++ b/src/dxr3/dxr3_decode_video.c @@ -40,8 +40,8 @@ #define LOG_VID 0 #define LOG_PTS 0 -#include "xine_internal.h" -#include "buffer.h" +#include +#include #include "video_out_dxr3.h" #include "dxr3.h" diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c index 0c59b0b93..19ff8b81d 100644 --- a/src/dxr3/dxr3_mpeg_encoders.c +++ b/src/dxr3/dxr3_mpeg_encoders.c @@ -48,7 +48,7 @@ /* #define LOG_VERBOSE */ /* #define LOG */ -#include "xineutils.h" +#include #include "video_out_dxr3.h" /* buffer size for encoded mpeg1 stream; will hold one intra frame diff --git a/src/dxr3/dxr3_scr.h b/src/dxr3/dxr3_scr.h index d0e155c27..b9f35d643 100644 --- a/src/dxr3/dxr3_scr.h +++ b/src/dxr3/dxr3_scr.h @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ -#include "xine_internal.h" +#include /* plugin structure */ diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c index b073e6f63..a2153dacc 100644 --- a/src/dxr3/video_out_dxr3.c +++ b/src/dxr3/video_out_dxr3.c @@ -60,9 +60,9 @@ #define LOG_VID 0 #define LOG_OVR 0 -#include "xine_internal.h" -#include "xineutils.h" -#include "video_out.h" +#include +#include +#include #include "dxr3.h" #include "video_out_dxr3.h" diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h index 0297204dd..a5a1368a3 100644 --- a/src/dxr3/video_out_dxr3.h +++ b/src/dxr3/video_out_dxr3.h @@ -26,7 +26,7 @@ # include #endif -#include "xine_internal.h" +#include #include "vo_scale.h" #include "dxr3_scr.h" #include "dxr3.h" diff --git a/src/input/Makefile.am b/src/input/Makefile.am index ed32ad7c5..8330b6d43 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -19,7 +19,6 @@ SUBDIRS += libdvdnav endif -xineinclude_HEADERS = input_plugin.h noinst_HEADERS = net_buf_ctrl.h mms.h mmsh.h pnm.h media_helper.h http_helper.h diff --git a/src/input/http_helper.c b/src/input/http_helper.c index 279d3ff05..83562c9dc 100644 --- a/src/input/http_helper.c +++ b/src/input/http_helper.c @@ -26,7 +26,7 @@ #include -#include "xine_internal.h" +#include #include "http_helper.h" int _x_parse_url (char *url, char **proto, char** host, int *port, diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c index ed6f2b4f9..c08e1ca0b 100644 --- a/src/input/input_cdda.c +++ b/src/input/input_cdda.c @@ -66,9 +66,9 @@ #include "sha1.h" #include "base64.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "media_helper.h" #if defined(__sun) diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 1151d9a81..b35f35fa6 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -113,9 +113,9 @@ #define LOG_READS */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "net_buf_ctrl.h" #define BUFSIZE 16384 diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index 8656097bc..3c06bdec5 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -85,9 +85,9 @@ #endif /* Xine includes */ -#include "xineutils.h" -#include "buffer.h" -#include "xine_internal.h" +#include +#include +#include #include "media_helper.h" /* Print debug messages? */ diff --git a/src/input/input_file.c b/src/input/input_file.c index 1556afb09..2fe3925ea 100644 --- a/src/input/input_file.c +++ b/src/input/input_file.c @@ -44,10 +44,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "input_plugin.h" +#include +#include +#include +#include #define MAXFILES 65535 diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c index 71a4ada85..e93a747ee 100644 --- a/src/input/input_gnome_vfs.c +++ b/src/input/input_gnome_vfs.c @@ -24,9 +24,9 @@ #include "config.h" #endif -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "net_buf_ctrl.h" #include diff --git a/src/input/input_http.c b/src/input/input_http.c index ef2606413..c2836affe 100644 --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -46,9 +46,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "net_buf_ctrl.h" #include "http_helper.h" diff --git a/src/input/input_mms.c b/src/input/input_mms.c index 0b9e6c7f2..0287e0060 100644 --- a/src/input/input_mms.c +++ b/src/input/input_mms.c @@ -41,9 +41,9 @@ */ #include "bswap.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "mms.h" #include "mmsh.h" diff --git a/src/input/input_net.c b/src/input/input_net.c index 7a52f670d..1d7288f41 100644 --- a/src/input/input_net.c +++ b/src/input/input_net.c @@ -66,9 +66,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "net_buf_ctrl.h" #define NET_BS_LEN 2324 diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c index 3bc026b69..3271a04c9 100644 --- a/src/input/input_pnm.c +++ b/src/input/input_pnm.c @@ -41,9 +41,9 @@ */ #include "bswap.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "pnm.h" #include "net_buf_ctrl.h" diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c index 40bb9dc79..d68b3fe34 100644 --- a/src/input/input_pvr.c +++ b/src/input/input_pvr.c @@ -108,10 +108,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "input_plugin.h" +#include +#include +#include +#include #define PVR_DEVICE "/dev/video0" diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c index c3abf4bf5..33183e555 100644 --- a/src/input/input_rtp.c +++ b/src/input/input_rtp.c @@ -91,9 +91,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "net_buf_ctrl.h" #ifdef __GNUC__ diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c index 690507d88..bee192c0d 100644 --- a/src/input/input_rtsp.c +++ b/src/input/input_rtsp.c @@ -41,9 +41,9 @@ */ #include "bswap.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "librtsp/rtsp_session.h" #include "net_buf_ctrl.h" diff --git a/src/input/input_smb.c b/src/input/input_smb.c index 8bbbfdfe5..44fa96bfd 100644 --- a/src/input/input_smb.c +++ b/src/input/input_smb.c @@ -23,10 +23,10 @@ #include "config.h" #endif -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "input_plugin.h" +#include +#include +#include +#include #include #include diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c index e28a8d0c3..d67954ea8 100644 --- a/src/input/input_stdin_fifo.c +++ b/src/input/input_stdin_fifo.c @@ -36,9 +36,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "net_buf_ctrl.h" #define BUFSIZE 1024 diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index ff9ea87d0..58f982da6 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -88,9 +88,9 @@ static char *log_line_prefix() } #endif -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #define NUM_FRAMES 15 diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c index 14a924a2a..4b624a9e7 100644 --- a/src/input/input_vcd.c +++ b/src/input/input_vcd.c @@ -45,9 +45,9 @@ #error "you need to add cdrom / VCD support for your platform to input_vcd and configure.in" #endif -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "media_helper.h" #if defined(__sun) diff --git a/src/input/libdvdnav/dvd_reader.c b/src/input/libdvdnav/dvd_reader.c index 200a1dbec..c15a5c3f5 100644 --- a/src/input/libdvdnav/dvd_reader.c +++ b/src/input/libdvdnav/dvd_reader.c @@ -70,7 +70,7 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz ) #include #endif -#include "compat.h" +#include #include "dvd_udf.h" #include "dvd_input.h" #include "dvd_reader.h" diff --git a/src/input/libreal/asmrp.c b/src/input/libreal/asmrp.c index f7206b583..9fc7a3867 100644 --- a/src/input/libreal/asmrp.c +++ b/src/input/libreal/asmrp.c @@ -43,7 +43,7 @@ */ #include "asmrp.h" -#include "xineutils.h" +#include #define ASMRP_SYM_NONE 0 #define ASMRP_SYM_EOF 1 diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c index 29376868c..eb8540976 100644 --- a/src/input/libreal/real.c +++ b/src/input/libreal/real.c @@ -33,8 +33,8 @@ #include "real.h" #include "asmrp.h" #include "sdpplin.h" -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" #define XOR_TABLE_LEN 37 diff --git a/src/input/libreal/rmff.c b/src/input/libreal/rmff.c index 4fea74636..a15c50b23 100644 --- a/src/input/libreal/rmff.c +++ b/src/input/libreal/rmff.c @@ -27,7 +27,7 @@ #define LOG */ -#include "xineutils.h" +#include #include "bswap.h" #include "rmff.h" diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c index 5b22e9044..c81e88ac2 100644 --- a/src/input/libreal/sdpplin.c +++ b/src/input/libreal/sdpplin.c @@ -29,7 +29,7 @@ #include "rmff.h" #include "rtsp.h" #include "sdpplin.h" -#include "xineutils.h" +#include /* * Decodes base64 strings (based upon b64 package) diff --git a/src/input/librtsp/rtsp.c b/src/input/librtsp/rtsp.c index d0f09d563..7607f2221 100644 --- a/src/input/librtsp/rtsp.c +++ b/src/input/librtsp/rtsp.c @@ -45,8 +45,8 @@ */ #include "rtsp.h" -#include "io_helper.h" -#include "xineutils.h" +#include +#include #define BUF_SIZE 4096 #define HEADER_SIZE 1024 diff --git a/src/input/librtsp/rtsp.h b/src/input/librtsp/rtsp.h index 7f7a3ddba..3c829e2e8 100644 --- a/src/input/librtsp/rtsp.h +++ b/src/input/librtsp/rtsp.h @@ -25,7 +25,7 @@ #define HAVE_RTSP_H /*#include */ -#include "xine_internal.h" +#include #ifdef __CYGWIN__ #define uint32_t unsigned int diff --git a/src/input/librtsp/rtsp_session.c b/src/input/librtsp/rtsp_session.c index 84552503b..e9ce5bc5c 100644 --- a/src/input/librtsp/rtsp_session.c +++ b/src/input/librtsp/rtsp_session.c @@ -41,7 +41,7 @@ #include "real.h" #include "rmff.h" #include "asmrp.h" -#include "xineutils.h" +#include #define BUF_SIZE 4096 #define HEADER_SIZE 4096 diff --git a/src/input/media_helper.h b/src/input/media_helper.h index 7e6303dfd..a8e376fdc 100644 --- a/src/input/media_helper.h +++ b/src/input/media_helper.h @@ -22,7 +22,7 @@ #ifndef HAVE_MEDIA_HELPER_H #define HAVE_MEDIA_HELPER_H -#include "xine_internal.h" +#include int media_eject_media (xine_t *xine, const char *device); diff --git a/src/input/mms.c b/src/input/mms.c index f11a89cf3..ccc56b094 100644 --- a/src/input/mms.c +++ b/src/input/mms.c @@ -56,8 +56,8 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" #include "http_helper.h" diff --git a/src/input/mms.h b/src/input/mms.h index a483fa0c6..67ea5ba0b 100644 --- a/src/input/mms.h +++ b/src/input/mms.h @@ -24,7 +24,7 @@ #define HAVE_MMS_H #include -#include "xine_internal.h" +#include typedef struct mms_s mms_t; diff --git a/src/input/mmsh.c b/src/input/mmsh.c index ae1c62bc1..f6bf0bcb6 100644 --- a/src/input/mmsh.c +++ b/src/input/mmsh.c @@ -51,8 +51,8 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "bswap.h" #include "http_helper.h" diff --git a/src/input/mmsh.h b/src/input/mmsh.h index 633d3b5f6..eeceb030b 100644 --- a/src/input/mmsh.h +++ b/src/input/mmsh.h @@ -24,7 +24,7 @@ #define HAVE_MMSH_H #include -#include "xine_internal.h" +#include typedef struct mmsh_s mmsh_t; diff --git a/src/input/net_buf_ctrl.h b/src/input/net_buf_ctrl.h index 79f698008..c35187179 100644 --- a/src/input/net_buf_ctrl.h +++ b/src/input/net_buf_ctrl.h @@ -23,7 +23,7 @@ #ifndef HAVE_NET_BUF_CTRL_H #define HAVE_NET_BUF_CTRL_H -#include "xine_internal.h" +#include typedef struct nbc_s nbc_t; diff --git a/src/input/pnm.c b/src/input/pnm.c index 942e52957..3cb36ac3f 100644 --- a/src/input/pnm.c +++ b/src/input/pnm.c @@ -45,9 +45,9 @@ #include "pnm.h" #include "libreal/rmff.h" #include "bswap.h" -#include "io_helper.h" -#include "xineutils.h" -#include "xine_internal.h" +#include +#include +#include #define BUF_SIZE 4096 #define HEADER_SIZE 4096 diff --git a/src/input/pnm.h b/src/input/pnm.h index 838fbadcc..bf3514bae 100644 --- a/src/input/pnm.h +++ b/src/input/pnm.h @@ -26,7 +26,7 @@ #ifndef __CYGWIN__ #include #endif -#include "xine_internal.h" +#include typedef struct pnm_s pnm_t; diff --git a/src/input/vcd/xine-extra.h b/src/input/vcd/xine-extra.h index 0650f863d..4246405ba 100644 --- a/src/input/vcd/xine-extra.h +++ b/src/input/vcd/xine-extra.h @@ -36,9 +36,9 @@ #endif /* Xine includes */ -#include "xine_internal.h" +#include #include "input_plugin.h" -#include "xineutils.h" +#include /*! This routine is like xine_log, except it takes a va_list instead of diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c index b794331f1..27b1cfbbf 100644 --- a/src/input/vcd/xineplug_inp_vcd.c +++ b/src/input/vcd/xineplug_inp_vcd.c @@ -52,8 +52,8 @@ #define xine_config_entry_t xine_cfg_entry_t /* Xine includes */ -#include "xineutils.h" -#include "input_plugin.h" +#include +#include #include "xine-extra.h" diff --git a/src/libffmpeg/ff_audio_decoder.c b/src/libffmpeg/ff_audio_decoder.c index 6dd9205ea..dd03cd2a3 100644 --- a/src/libffmpeg/ff_audio_decoder.c +++ b/src/libffmpeg/ff_audio_decoder.c @@ -40,9 +40,9 @@ #define LOG */ -#include "xine_internal.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include #include "bswap.h" #include "ffmpeg_decoder.h" diff --git a/src/libffmpeg/ff_dvaudio_decoder.c b/src/libffmpeg/ff_dvaudio_decoder.c index 482ae396e..aced7f5bb 100644 --- a/src/libffmpeg/ff_dvaudio_decoder.c +++ b/src/libffmpeg/ff_dvaudio_decoder.c @@ -36,9 +36,9 @@ #define LOG */ -#include "xine_internal.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include #ifdef _MSC_VER /* ffmpeg has own definitions of those types */ diff --git a/src/libffmpeg/ff_mpeg_parser.h b/src/libffmpeg/ff_mpeg_parser.h index ea43a6ce4..504e746f9 100644 --- a/src/libffmpeg/ff_mpeg_parser.h +++ b/src/libffmpeg/ff_mpeg_parser.h @@ -23,7 +23,7 @@ #ifndef HAVE_MPEG_PARSER_H #define HAVE_MPEG_PARSER_H -#include "xine_internal.h" +#include #include "ffmpeg_decoder.h" #define BUFFER_SIZE (1194 * 1024) /* libmpeg2's buffer size */ diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index 0b8728f06..4e5e1ebdf 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -40,10 +40,10 @@ /* #define LOG */ -#include "xine_internal.h" +#include #include "bswap.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include #include "ffmpeg_decoder.h" #include "ff_mpeg_parser.h" diff --git a/src/libffmpeg/ffmpeg_decoder.c b/src/libffmpeg/ffmpeg_decoder.c index 45080590d..8a8a79270 100644 --- a/src/libffmpeg/ffmpeg_decoder.c +++ b/src/libffmpeg/ffmpeg_decoder.c @@ -24,7 +24,7 @@ #include "config.h" #endif -#include "xine_internal.h" +#include #include "ffmpeg_decoder.h" diff --git a/src/libmpeg2/cpu_state.c b/src/libmpeg2/cpu_state.c index 07b4c5b7e..12963644c 100644 --- a/src/libmpeg2/cpu_state.c +++ b/src/libmpeg2/cpu_state.c @@ -27,7 +27,7 @@ #include #include "mpeg2_internal.h" -#include "xineutils.h" +#include void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index 58f34ccbc..145d5f58b 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -37,11 +37,11 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" +#include +#include #include "mpeg2.h" #include "mpeg2_internal.h" -#include "xineutils.h" +#include #include "libmpeg2_accel.h" /* diff --git a/src/libmpeg2/header.c b/src/libmpeg2/header.c index 7f1ef1fc8..12ba0ff8a 100644 --- a/src/libmpeg2/header.c +++ b/src/libmpeg2/header.c @@ -31,7 +31,7 @@ #include #include "mpeg2_internal.h" -#include "attributes.h" +#include /* default intra quant matrix, in zig-zag order */ static const uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = { diff --git a/src/libmpeg2/idct.c b/src/libmpeg2/idct.c index 157beea31..9f216db58 100644 --- a/src/libmpeg2/idct.c +++ b/src/libmpeg2/idct.c @@ -46,7 +46,7 @@ #include #include "mpeg2_internal.h" -#include "xineutils.h" +#include #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ diff --git a/src/libmpeg2/idct_altivec.c b/src/libmpeg2/idct_altivec.c index ed8b58cfd..de396560b 100644 --- a/src/libmpeg2/idct_altivec.c +++ b/src/libmpeg2/idct_altivec.c @@ -30,7 +30,7 @@ #include #include "mpeg2_internal.h" -#include "xineutils.h" +#include #define vector_s16_t vector signed short #define vector_u16_t vector unsigned short diff --git a/src/libmpeg2/idct_mmx.c b/src/libmpeg2/idct_mmx.c index ce4bd064b..6bb4bfbf0 100644 --- a/src/libmpeg2/idct_mmx.c +++ b/src/libmpeg2/idct_mmx.c @@ -28,7 +28,7 @@ #include #include "mpeg2_internal.h" -#include "xineutils.h" +#include #define ROW_SHIFT 11 #define COL_SHIFT 6 diff --git a/src/libmpeg2/libmpeg2_accel.c b/src/libmpeg2/libmpeg2_accel.c index 63c7b1b9b..92c0e280b 100644 --- a/src/libmpeg2/libmpeg2_accel.c +++ b/src/libmpeg2/libmpeg2_accel.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include "xine_internal.h" +#include #include "mpeg2.h" #include "mpeg2_internal.h" #include "xvmc_vld.h" diff --git a/src/libmpeg2/motion_comp.c b/src/libmpeg2/motion_comp.c index 8779c1296..9328dfb9f 100644 --- a/src/libmpeg2/motion_comp.c +++ b/src/libmpeg2/motion_comp.c @@ -27,7 +27,7 @@ #include #include "mpeg2_internal.h" -#include "xineutils.h" +#include mpeg2_mc_t mpeg2_mc; diff --git a/src/libmpeg2/motion_comp_mmx.c b/src/libmpeg2/motion_comp_mmx.c index 80a53685a..f9b1f085d 100644 --- a/src/libmpeg2/motion_comp_mmx.c +++ b/src/libmpeg2/motion_comp_mmx.c @@ -28,7 +28,7 @@ #include #include "mpeg2_internal.h" -#include "xineutils.h" +#include #define CPU_MMXEXT 0 #define CPU_3DNOW 1 diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h index c2ffbf909..2e42aace6 100644 --- a/src/libmpeg2/mpeg2_internal.h +++ b/src/libmpeg2/mpeg2_internal.h @@ -24,7 +24,7 @@ #ifndef MPEG2_INTERNAL_H #define MPEG2_INTERNAL_H -#include "video_out.h" +#include #include "accel_xvmc.h" #ifdef ENABLE_ALTIVEC diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c index 91a4c47b1..8247a9a24 100644 --- a/src/libmpeg2/slice.c +++ b/src/libmpeg2/slice.c @@ -25,10 +25,10 @@ #include -#include "xine_internal.h" -#include "video_out.h" +#include +#include #include "mpeg2_internal.h" -#include "attributes.h" +#include #include "vlc.h" diff --git a/src/libmpeg2/slice_xvmc.c b/src/libmpeg2/slice_xvmc.c index e21b1eb98..014ae7924 100644 --- a/src/libmpeg2/slice_xvmc.c +++ b/src/libmpeg2/slice_xvmc.c @@ -28,12 +28,12 @@ #include #include -#include "xine_internal.h" -#include "video_out.h" +#include +#include #include "mpeg2_internal.h" -#include "xineutils.h" +#include -#include "attributes.h" +#include #include "accel_xvmc.h" #include "xvmc.h" diff --git a/src/libmpeg2/slice_xvmc_vld.c b/src/libmpeg2/slice_xvmc_vld.c index 7e370a519..3606cf66b 100644 --- a/src/libmpeg2/slice_xvmc_vld.c +++ b/src/libmpeg2/slice_xvmc_vld.c @@ -17,8 +17,8 @@ * */ -#include "xine_internal.h" -#include "video_out.h" +#include +#include #include "mpeg2.h" #include "mpeg2_internal.h" #include "xvmc_vld.h" diff --git a/src/libmpeg2/xine_mpeg2_decoder.c b/src/libmpeg2/xine_mpeg2_decoder.c index ccce02186..3a3e28452 100644 --- a/src/libmpeg2/xine_mpeg2_decoder.c +++ b/src/libmpeg2/xine_mpeg2_decoder.c @@ -34,11 +34,11 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" +#include +#include #include "mpeg2.h" #include "mpeg2_internal.h" -#include "buffer.h" +#include typedef struct { video_decoder_class_t decoder_class; diff --git a/src/libmpeg2new/libmpeg2/idct_alpha.c b/src/libmpeg2new/libmpeg2/idct_alpha.c index 8f9beaf22..1d8fd08ee 100644 --- a/src/libmpeg2new/libmpeg2/idct_alpha.c +++ b/src/libmpeg2new/libmpeg2/idct_alpha.c @@ -30,7 +30,7 @@ #include #include "mpeg2.h" -#include "attributes.h" +#include #include "mpeg2_internal.h" #include "alpha_asm.h" diff --git a/src/libmpeg2new/libmpeg2/idct_altivec.c b/src/libmpeg2new/libmpeg2/idct_altivec.c index 6b1b8586c..f15bca165 100644 --- a/src/libmpeg2new/libmpeg2/idct_altivec.c +++ b/src/libmpeg2new/libmpeg2/idct_altivec.c @@ -31,7 +31,7 @@ #include #include "mpeg2.h" -#include "attributes.h" +#include #include "mpeg2_internal.h" typedef vector signed char vector_s8_t; diff --git a/src/libmpeg2new/libmpeg2/motion_comp_alpha.c b/src/libmpeg2new/libmpeg2/motion_comp_alpha.c index 05cd55084..1b3712a1a 100644 --- a/src/libmpeg2new/libmpeg2/motion_comp_alpha.c +++ b/src/libmpeg2new/libmpeg2/motion_comp_alpha.c @@ -27,7 +27,7 @@ #include #include "mpeg2.h" -#include "attributes.h" +#include #include "mpeg2_internal.h" #include "alpha_asm.h" diff --git a/src/libmpeg2new/libmpeg2/motion_comp_altivec.c b/src/libmpeg2new/libmpeg2/motion_comp_altivec.c index 4356aa6e7..ee740e14e 100644 --- a/src/libmpeg2new/libmpeg2/motion_comp_altivec.c +++ b/src/libmpeg2new/libmpeg2/motion_comp_altivec.c @@ -31,7 +31,7 @@ #include #include "mpeg2.h" -#include "attributes.h" +#include #include "mpeg2_internal.h" typedef vector signed char vector_s8_t; diff --git a/src/libmpeg2new/libmpeg2/motion_comp_vis.c b/src/libmpeg2new/libmpeg2/motion_comp_vis.c index 54c0f7e75..e724d28a2 100644 --- a/src/libmpeg2new/libmpeg2/motion_comp_vis.c +++ b/src/libmpeg2new/libmpeg2/motion_comp_vis.c @@ -27,7 +27,7 @@ #include #include "mpeg2.h" -#include "attributes.h" +#include #include "mpeg2_internal.h" #include "vis.h" diff --git a/src/libmpeg2new/libmpeg2/rgb.c b/src/libmpeg2new/libmpeg2/rgb.c index 8863b0b9f..e4abcacc2 100644 --- a/src/libmpeg2new/libmpeg2/rgb.c +++ b/src/libmpeg2new/libmpeg2/rgb.c @@ -22,7 +22,7 @@ */ #include "config.h" -#include "attributes.h" +#include #include diff --git a/src/libmpeg2new/libmpeg2/rgb_mmx.c b/src/libmpeg2new/libmpeg2/rgb_mmx.c index 912291c6a..6ca7e65a8 100644 --- a/src/libmpeg2new/libmpeg2/rgb_mmx.c +++ b/src/libmpeg2new/libmpeg2/rgb_mmx.c @@ -34,7 +34,7 @@ #include "mpeg2.h" #include "mpeg2convert.h" #include "convert_internal.h" -#include "attributes.h" +#include #include "mmx.h" #define CPU_MMXEXT 0 diff --git a/src/libmpeg2new/libmpeg2/rgb_vis.c b/src/libmpeg2new/libmpeg2/rgb_vis.c index 49d8d1d7c..cbd7c7072 100644 --- a/src/libmpeg2new/libmpeg2/rgb_vis.c +++ b/src/libmpeg2new/libmpeg2/rgb_vis.c @@ -30,7 +30,7 @@ #include "mpeg2.h" #include "mpeg2convert.h" #include "convert_internal.h" -#include "attributes.h" +#include #include "vis.h" /* Based partially upon the MMX yuv2rgb code, see there for credits. diff --git a/src/libmpeg2new/xine_mpeg2new_decoder.c b/src/libmpeg2new/xine_mpeg2new_decoder.c index 386b0049d..eeafee9c1 100644 --- a/src/libmpeg2new/xine_mpeg2new_decoder.c +++ b/src/libmpeg2new/xine_mpeg2new_decoder.c @@ -31,9 +31,9 @@ #include #include "./include/mpeg2.h" -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" +#include +#include +#include diff --git a/src/libreal/real_common.h b/src/libreal/real_common.h index 1e3d8c264..74dc5e6e2 100644 --- a/src/libreal/real_common.h +++ b/src/libreal/real_common.h @@ -23,7 +23,7 @@ #ifndef __REAL_COMMON_H__ #define __REAL_COMMON_H__ -#include "xine_internal.h" +#include /* * some fake functions to make real codecs happy diff --git a/src/libreal/xine_real_audio_decoder.c b/src/libreal/xine_real_audio_decoder.c index 5c43f8480..bc928975d 100644 --- a/src/libreal/xine_real_audio_decoder.c +++ b/src/libreal/xine_real_audio_decoder.c @@ -38,10 +38,10 @@ */ #include "bswap.h" -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "real_common.h" diff --git a/src/libreal/xine_real_video_decoder.c b/src/libreal/xine_real_video_decoder.c index 617c9f6b5..a32b3d3ef 100644 --- a/src/libreal/xine_real_video_decoder.c +++ b/src/libreal/xine_real_video_decoder.c @@ -37,10 +37,10 @@ #define LOG */ #include "bswap.h" -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "real_common.h" diff --git a/src/libspucc/cc_decoder.c b/src/libspucc/cc_decoder.c index 8d666e847..e8fc09895 100644 --- a/src/libspucc/cc_decoder.c +++ b/src/libspucc/cc_decoder.c @@ -35,12 +35,12 @@ #include -#include "xine_internal.h" -#include "video_out.h" -#include "xineutils.h" -#include "osd.h" +#include +#include +#include +#include #include "cc_decoder.h" -#include "osd.h" +#include /* #define LOG_DEBUG 3 diff --git a/src/libspucc/xine_cc_decoder.c b/src/libspucc/xine_cc_decoder.c index 1e31b6d4a..e8a02a996 100644 --- a/src/libspucc/xine_cc_decoder.c +++ b/src/libspucc/xine_cc_decoder.c @@ -24,9 +24,9 @@ #include #include -#include "buffer.h" -#include "xine_internal.h" -#include "xineutils.h" +#include +#include +#include #include "cc_decoder.h" /* diff --git a/src/libspucmml/xine_cmml_decoder.c b/src/libspucmml/xine_cmml_decoder.c index 6c045ee04..6ce6d3f90 100644 --- a/src/libspucmml/xine_cmml_decoder.c +++ b/src/libspucmml/xine_cmml_decoder.c @@ -30,7 +30,7 @@ #define SUB_BUFSIZE 1024 #define SUB_MAX_TEXT 5 -#include "xine_internal.h" +#include typedef enum { SUBTITLE_SIZE_SMALL = 0, diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c index ce3497ef0..c836dbf58 100644 --- a/src/libspudec/spu.c +++ b/src/libspudec/spu.c @@ -47,10 +47,10 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include "spu.h" -#include "buffer.h" +#include #include "xine-engine/bswap.h" #ifdef HAVE_DVDNAV # include diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h index 8d92146f0..1e7d80596 100644 --- a/src/libspudec/spu.h +++ b/src/libspudec/spu.h @@ -30,8 +30,8 @@ #endif #include -#include "video_out.h" -#include "video_overlay.h" +#include +#include #ifdef HAVE_DVDNAV # include #else diff --git a/src/libspudec/xine_spu_decoder.c b/src/libspudec/xine_spu_decoder.c index 93ea3c3a2..7f0269dfb 100644 --- a/src/libspudec/xine_spu_decoder.c +++ b/src/libspudec/xine_spu_decoder.c @@ -29,10 +29,10 @@ #include #include -#include "xine_internal.h" -#include "buffer.h" +#include +#include #include "xine-engine/bswap.h" -#include "xineutils.h" +#include #include "spu.h" #ifdef HAVE_DVDNAV # include diff --git a/src/libspudvb/xine_spudvb_decoder.c b/src/libspudvb/xine_spudvb_decoder.c index 59790227c..9008260f7 100644 --- a/src/libspudvb/xine_spudvb_decoder.c +++ b/src/libspudvb/xine_spudvb_decoder.c @@ -27,9 +27,9 @@ #include "pthread.h" #include -#include "xine_internal.h" -#include "spu.h" -#include "osd.h" +#include +#include +#include #define MAX_REGIONS 7 /*#define LOG 1*/ diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index 811bdcbd6..270894f50 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.c @@ -47,9 +47,9 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "../demuxers/demux.h" +#include +#include +#include #define ERR (void *)-1 #define SUB_MAX_TEXT 5 diff --git a/src/libsputext/xine_sputext_decoder.c b/src/libsputext/xine_sputext_decoder.c index d28e67829..12d1986bb 100644 --- a/src/libsputext/xine_sputext_decoder.c +++ b/src/libsputext/xine_sputext_decoder.c @@ -33,10 +33,10 @@ #define LOG */ -#include "buffer.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "osd.h" +#include +#include +#include +#include #define SUB_MAX_TEXT 5 /* lines */ #define SUB_BUFSIZE 256 /* chars per line */ diff --git a/src/libw32dll/qt_decoder.c b/src/libw32dll/qt_decoder.c index ca358bb9b..64e30d637 100644 --- a/src/libw32dll/qt_decoder.c +++ b/src/libw32dll/qt_decoder.c @@ -38,9 +38,9 @@ */ #include "bswap.h" -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" +#include +#include +#include #include "qtx/qtxsdk/components.h" #include "wine/win32.h" diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c index 3b66dfb23..bcb5db53c 100644 --- a/src/libw32dll/w32codec.c +++ b/src/libw32dll/w32codec.c @@ -50,11 +50,11 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include +#include #include "common.c" diff --git a/src/libw32dll/wine/registry.c b/src/libw32dll/wine/registry.c index c8e3c4dd0..20c21888d 100644 --- a/src/libw32dll/wine/registry.c +++ b/src/libw32dll/wine/registry.c @@ -18,7 +18,7 @@ #include "debugtools.h" #ifdef XINE_MAJOR -#include "xineutils.h" +#include #include #endif diff --git a/src/libw32dll/wine/win32.c b/src/libw32dll/wine/win32.c index 3b0941391..ce8132d3f 100644 --- a/src/libw32dll/wine/win32.c +++ b/src/libw32dll/wine/win32.c @@ -12,7 +12,7 @@ for DLL to know too much about its environment. ************************************************************/ #include "config.h" -#include "attributes.h" +#include #define QTX diff --git a/src/libxineadec/fooaudio.c b/src/libxineadec/fooaudio.c index 42427611f..b0ef63454 100644 --- a/src/libxineadec/fooaudio.c +++ b/src/libxineadec/fooaudio.c @@ -28,10 +28,10 @@ #include #include -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" /* math.h required for fooaudio sine wave generation */ diff --git a/src/libxineadec/gsm610.c b/src/libxineadec/gsm610.c index 4ca3827d7..8192aa7d8 100644 --- a/src/libxineadec/gsm610.c +++ b/src/libxineadec/gsm610.c @@ -52,10 +52,10 @@ #include #include -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" #include "private.h" diff --git a/src/libxineadec/xine_a52_decoder.c b/src/libxineadec/xine_a52_decoder.c index 2d901d00a..e34504553 100644 --- a/src/libxineadec/xine_a52_decoder.c +++ b/src/libxineadec/xine_a52_decoder.c @@ -44,8 +44,8 @@ #define LOG_PTS */ -#include "xine_internal.h" -#include "audio_out.h" +#include +#include #ifdef HAVE_A52DEC_A52_H # include @@ -59,8 +59,8 @@ # include "a52_internal.h" #endif -#include "buffer.h" -#include "xineutils.h" +#include +#include #include "../../contrib/a52dec/crc.c" diff --git a/src/libxineadec/xine_dts_decoder.c b/src/libxineadec/xine_dts_decoder.c index 369c354fd..9d2fc5e93 100644 --- a/src/libxineadec/xine_dts_decoder.c +++ b/src/libxineadec/xine_dts_decoder.c @@ -47,10 +47,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" -#include "buffer.h" +#include +#include +#include +#include #include "bswap.h" diff --git a/src/libxineadec/xine_faad_decoder.c b/src/libxineadec/xine_faad_decoder.c index c12e7816d..6b242005a 100644 --- a/src/libxineadec/xine_faad_decoder.c +++ b/src/libxineadec/xine_faad_decoder.c @@ -31,10 +31,10 @@ #define LOG */ -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #ifdef HAVE_NEAACDEC_H #include #else diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 96c02906d..51d2e3137 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -39,9 +39,9 @@ #include #include /* ntohs */ -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" +#include +#include +#include #ifdef WIN32 #include diff --git a/src/libxineadec/xine_mad_decoder.c b/src/libxineadec/xine_mad_decoder.c index 906db048a..21e5bf46b 100644 --- a/src/libxineadec/xine_mad_decoder.c +++ b/src/libxineadec/xine_mad_decoder.c @@ -34,10 +34,10 @@ #define LOG */ -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #ifdef HAVE_MAD_H # include diff --git a/src/libxineadec/xine_musepack_decoder.c b/src/libxineadec/xine_musepack_decoder.c index d23d1546c..268846a1a 100644 --- a/src/libxineadec/xine_musepack_decoder.c +++ b/src/libxineadec/xine_musepack_decoder.c @@ -39,10 +39,10 @@ #define LOG */ -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include diff --git a/src/libxinevdec/bitplane.c b/src/libxinevdec/bitplane.c index c8400f464..327e14aee 100644 --- a/src/libxinevdec/bitplane.c +++ b/src/libxinevdec/bitplane.c @@ -35,10 +35,10 @@ #include #include -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" #include "demuxers/iff.h" diff --git a/src/libxinevdec/foovideo.c b/src/libxinevdec/foovideo.c index b33705a3f..49c63422c 100644 --- a/src/libxinevdec/foovideo.c +++ b/src/libxinevdec/foovideo.c @@ -30,10 +30,10 @@ #include #include -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" #define VIDEOBUFSIZE 128*1024 diff --git a/src/libxinevdec/gdkpixbuf.c b/src/libxinevdec/gdkpixbuf.c index 7fd4a6a0e..28c9c77c7 100644 --- a/src/libxinevdec/gdkpixbuf.c +++ b/src/libxinevdec/gdkpixbuf.c @@ -35,10 +35,10 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" #include diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c index 7a97972c7..e84312624 100644 --- a/src/libxinevdec/image.c +++ b/src/libxinevdec/image.c @@ -44,10 +44,10 @@ #undef PACKAGE_VERSION #endif -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" typedef struct { diff --git a/src/libxinevdec/rgb.c b/src/libxinevdec/rgb.c index 5360fd8b2..9c8409e5f 100644 --- a/src/libxinevdec/rgb.c +++ b/src/libxinevdec/rgb.c @@ -42,10 +42,10 @@ /* #define LOG */ -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" typedef struct { diff --git a/src/libxinevdec/yuv.c b/src/libxinevdec/yuv.c index 352f59e9a..c1e5825c5 100644 --- a/src/libxinevdec/yuv.c +++ b/src/libxinevdec/yuv.c @@ -28,10 +28,10 @@ #include #include -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include +#include #include "bswap.h" #define VIDEOBUFSIZE 128*1024 diff --git a/src/post/audio/audio_filters.c b/src/post/audio/audio_filters.c index 8200db51b..b7f53499a 100644 --- a/src/post/audio/audio_filters.c +++ b/src/post/audio/audio_filters.c @@ -21,9 +21,9 @@ */ -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "audio_filters.h" diff --git a/src/post/audio/audio_filters.h b/src/post/audio/audio_filters.h index 6c064945a..8a0202751 100644 --- a/src/post/audio/audio_filters.h +++ b/src/post/audio/audio_filters.h @@ -20,7 +20,7 @@ * catalog for audio filter plugins */ -#include "xine_internal.h" +#include void *upmix_init_plugin(xine_t *xine, void *data); diff --git a/src/post/audio/stretch.c b/src/post/audio/stretch.c index f02b1b899..bc079fd8d 100644 --- a/src/post/audio/stretch.c +++ b/src/post/audio/stretch.c @@ -22,11 +22,11 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "dsp.h" -#include "resample.h" +#include #include "audio_filters.h" diff --git a/src/post/audio/upmix.c b/src/post/audio/upmix.c index 4d0e2c2a2..30fbb452b 100644 --- a/src/post/audio/upmix.c +++ b/src/post/audio/upmix.c @@ -26,9 +26,9 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "dsp.h" #include "audio_filters.h" diff --git a/src/post/audio/upmix_mono.c b/src/post/audio/upmix_mono.c index b28b1f3f5..53fd23109 100644 --- a/src/post/audio/upmix_mono.c +++ b/src/post/audio/upmix_mono.c @@ -31,8 +31,8 @@ #define LOG */ -#include "xineutils.h" -#include "post.h" +#include +#include #include "audio_filters.h" diff --git a/src/post/audio/volnorm.c b/src/post/audio/volnorm.c index 7533ba94a..4fb2a0411 100644 --- a/src/post/audio/volnorm.c +++ b/src/post/audio/volnorm.c @@ -25,9 +25,9 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "dsp.h" #include "audio_filters.h" diff --git a/src/post/deinterlace/deinterlace.c b/src/post/deinterlace/deinterlace.c index 8e4a3bb00..5c0356c55 100644 --- a/src/post/deinterlace/deinterlace.c +++ b/src/post/deinterlace/deinterlace.c @@ -31,7 +31,7 @@ */ #include "deinterlace.h" -#include "xine_internal.h" +#include typedef struct methodlist_item_s methodlist_item_t; diff --git a/src/post/deinterlace/plugins/greedy.c b/src/post/deinterlace/plugins/greedy.c index b5fcad3e5..fc8013a6d 100644 --- a/src/post/deinterlace/plugins/greedy.c +++ b/src/post/deinterlace/plugins/greedy.c @@ -32,8 +32,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" diff --git a/src/post/deinterlace/plugins/greedy2frame.c b/src/post/deinterlace/plugins/greedy2frame.c index 57e3228ac..af27d76ee 100644 --- a/src/post/deinterlace/plugins/greedy2frame.c +++ b/src/post/deinterlace/plugins/greedy2frame.c @@ -31,8 +31,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" diff --git a/src/post/deinterlace/plugins/kdetv_greedyh.c b/src/post/deinterlace/plugins/kdetv_greedyh.c index 5ec48e4a2..2207772ca 100644 --- a/src/post/deinterlace/plugins/kdetv_greedyh.c +++ b/src/post/deinterlace/plugins/kdetv_greedyh.c @@ -31,8 +31,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" diff --git a/src/post/deinterlace/plugins/kdetv_tomsmocomp.c b/src/post/deinterlace/plugins/kdetv_tomsmocomp.c index ae0fa0363..0f87b913f 100644 --- a/src/post/deinterlace/plugins/kdetv_tomsmocomp.c +++ b/src/post/deinterlace/plugins/kdetv_tomsmocomp.c @@ -31,8 +31,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" diff --git a/src/post/deinterlace/plugins/linearblend.c b/src/post/deinterlace/plugins/linearblend.c index 96e56063f..4664a4969 100644 --- a/src/post/deinterlace/plugins/linearblend.c +++ b/src/post/deinterlace/plugins/linearblend.c @@ -31,8 +31,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "speedtools.h" #include "speedy.h" #include "deinterlace.h" diff --git a/src/post/deinterlace/plugins/vfir.c b/src/post/deinterlace/plugins/vfir.c index e66d7c789..d66c92952 100644 --- a/src/post/deinterlace/plugins/vfir.c +++ b/src/post/deinterlace/plugins/vfir.c @@ -34,8 +34,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "speedy.h" #include "deinterlace.h" #include "plugins.h" diff --git a/src/post/deinterlace/speedy.c b/src/post/deinterlace/speedy.c index a980780d7..d93b56c7b 100644 --- a/src/post/deinterlace/speedy.c +++ b/src/post/deinterlace/speedy.c @@ -62,8 +62,8 @@ #include #endif -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "speedtools.h" #include "speedy.h" diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c index 68eabba67..5f3f8de97 100644 --- a/src/post/deinterlace/xine_plugin.c +++ b/src/post/deinterlace/xine_plugin.c @@ -27,10 +27,10 @@ #define LOG */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" -#include "xine_buffer.h" +#include +#include +#include +#include #include #include "tvtime.h" diff --git a/src/post/goom/goom_core.c b/src/post/goom/goom_core.c index b24f2f496..274059da4 100644 --- a/src/post/goom/goom_core.c +++ b/src/post/goom/goom_core.c @@ -26,7 +26,7 @@ #include "goom_fx.h" #include "goomsl.h" -#include "xine_internal.h" +#include /* #define VERBOSE */ diff --git a/src/post/goom/mmx.h b/src/post/goom/mmx.h index 88789e86f..6861b7cfe 100644 --- a/src/post/goom/mmx.h +++ b/src/post/goom/mmx.h @@ -31,7 +31,7 @@ # include "config.h" #endif -#include "attributes.h" +#include #include "goom_graphic.h" diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c index 0b540694d..50e72472b 100644 --- a/src/post/goom/xine_goom.c +++ b/src/post/goom/xine_goom.c @@ -35,9 +35,9 @@ */ #include "config.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "goom.h" diff --git a/src/post/mosaico/mosaico.c b/src/post/mosaico/mosaico.c index 5683002f6..a3e846026 100644 --- a/src/post/mosaico/mosaico.c +++ b/src/post/mosaico/mosaico.c @@ -28,8 +28,8 @@ #define LOG */ -#include "xine_internal.h" -#include "post.h" +#include +#include /* FIXME: This plugin needs to handle overlays as well. */ diff --git a/src/post/mosaico/switch.c b/src/post/mosaico/switch.c index 23469e566..de963c7b3 100644 --- a/src/post/mosaico/switch.c +++ b/src/post/mosaico/switch.c @@ -28,8 +28,8 @@ #define LOG */ -#include "xine_internal.h" -#include "post.h" +#include +#include /* FIXME: This plugin needs to handle overlays as well. */ diff --git a/src/post/planar/boxblur.c b/src/post/planar/boxblur.c index 225e75954..988729af0 100644 --- a/src/post/planar/boxblur.c +++ b/src/post/planar/boxblur.c @@ -21,9 +21,9 @@ * Copyright (C) 2002 Michael Niedermayer */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include /* plugin class initialization function */ diff --git a/src/post/planar/denoise3d.c b/src/post/planar/denoise3d.c index fb7021ece..bec59b35f 100644 --- a/src/post/planar/denoise3d.c +++ b/src/post/planar/denoise3d.c @@ -21,9 +21,9 @@ * Copyright (C) 2003 Daniel Moreno */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include #include diff --git a/src/post/planar/eq.c b/src/post/planar/eq.c index 03f647d68..e62a808c1 100644 --- a/src/post/planar/eq.c +++ b/src/post/planar/eq.c @@ -21,9 +21,9 @@ * Copyright (C) Richard Felker */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include diff --git a/src/post/planar/eq2.c b/src/post/planar/eq2.c index ceb9f9024..42f4580d9 100644 --- a/src/post/planar/eq2.c +++ b/src/post/planar/eq2.c @@ -25,9 +25,9 @@ * Richard Felker (original MMX contrast/brightness code (vf_eq.c)) */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include #include diff --git a/src/post/planar/expand.c b/src/post/planar/expand.c index db62a5512..90547163f 100644 --- a/src/post/planar/expand.c +++ b/src/post/planar/expand.c @@ -27,8 +27,8 @@ * */ -#include "xine_internal.h" -#include "post.h" +#include +#include /* The expand trick explained: * diff --git a/src/post/planar/fill.c b/src/post/planar/fill.c index 62fdc1381..6dd5ce23b 100644 --- a/src/post/planar/fill.c +++ b/src/post/planar/fill.c @@ -22,8 +22,8 @@ * based on invert.c */ -#include "xine_internal.h" -#include "post.h" +#include +#include /* plugin class initialization function */ void *fill_init_plugin(xine_t *xine, void *); diff --git a/src/post/planar/invert.c b/src/post/planar/invert.c index b5ee1e3f2..8c1b6103a 100644 --- a/src/post/planar/invert.c +++ b/src/post/planar/invert.c @@ -22,8 +22,8 @@ * simple video inverter plugin */ -#include "xine_internal.h" -#include "post.h" +#include +#include /* plugin class initialization function */ diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c index afe05b180..90ec331ee 100644 --- a/src/post/planar/noise.c +++ b/src/post/planar/noise.c @@ -21,9 +21,9 @@ * is copyright 2002 Michael Niedermayer */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include #include diff --git a/src/post/planar/planar.c b/src/post/planar/planar.c index 5907d58e5..220fce68e 100644 --- a/src/post/planar/planar.c +++ b/src/post/planar/planar.c @@ -20,9 +20,9 @@ * catalog for planar post plugins */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include extern void *invert_init_plugin(xine_t *xine, void *); static const post_info_t invert_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; diff --git a/src/post/planar/pp.c b/src/post/planar/pp.c index 3f9c0d745..484afdd31 100644 --- a/src/post/planar/pp.c +++ b/src/post/planar/pp.c @@ -20,9 +20,9 @@ * plugin for ffmpeg libpostprocess */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include "postprocess.h" #include diff --git a/src/post/planar/unsharp.c b/src/post/planar/unsharp.c index ff86f21bc..591f32a7b 100644 --- a/src/post/planar/unsharp.c +++ b/src/post/planar/unsharp.c @@ -21,9 +21,9 @@ * Copyright (C) 2002 Rémi Guyomarch */ -#include "xine_internal.h" -#include "post.h" -#include "xineutils.h" +#include +#include +#include #include #ifndef MIN diff --git a/src/post/visualizations/fftgraph.c b/src/post/visualizations/fftgraph.c index 7e7f52fbf..c31c529f2 100644 --- a/src/post/visualizations/fftgraph.c +++ b/src/post/visualizations/fftgraph.c @@ -26,9 +26,9 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "bswap.h" #include "visualizations.h" #include "fft.h" diff --git a/src/post/visualizations/fftscope.c b/src/post/visualizations/fftscope.c index 917af508d..dd474bd6f 100644 --- a/src/post/visualizations/fftscope.c +++ b/src/post/visualizations/fftscope.c @@ -26,9 +26,9 @@ #include #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "bswap.h" #include "visualizations.h" #include "fft.h" diff --git a/src/post/visualizations/fooviz.c b/src/post/visualizations/fooviz.c index 78803f8d2..54cd65db4 100644 --- a/src/post/visualizations/fooviz.c +++ b/src/post/visualizations/fooviz.c @@ -26,9 +26,9 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #define FPS 20 diff --git a/src/post/visualizations/oscope.c b/src/post/visualizations/oscope.c index 86b8b2750..1d498980a 100644 --- a/src/post/visualizations/oscope.c +++ b/src/post/visualizations/oscope.c @@ -23,9 +23,9 @@ #include -#include "xine_internal.h" -#include "xineutils.h" -#include "post.h" +#include +#include +#include #include "visualizations.h" #define FPS 20 diff --git a/src/post/visualizations/visualizations.c b/src/post/visualizations/visualizations.c index a26f0bd5b..db111bdd8 100644 --- a/src/post/visualizations/visualizations.c +++ b/src/post/visualizations/visualizations.c @@ -24,8 +24,8 @@ #include "config.h" #endif -#include "xine_internal.h" -#include "post.h" +#include +#include #include "visualizations.h" diff --git a/src/post/visualizations/visualizations.h b/src/post/visualizations/visualizations.h index 39d02e1cb..c72a1ad77 100644 --- a/src/post/visualizations/visualizations.h +++ b/src/post/visualizations/visualizations.h @@ -20,7 +20,7 @@ * This file contains plugin entries for several visualization post plugins. */ -#include "xine_internal.h" +#include void *oscope_init_plugin(xine_t *xine, void *data); void *fftscope_init_plugin(xine_t *xine, void *data); diff --git a/src/vdr/input_vdr.c b/src/vdr/input_vdr.c index 946e963a3..545e3fcc2 100644 --- a/src/vdr/input_vdr.c +++ b/src/vdr/input_vdr.c @@ -41,9 +41,9 @@ /* #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" +#include +#include +#include #include "input_vdr.h" #include "post_vdr.h" diff --git a/src/vdr/post_vdr.c b/src/vdr/post_vdr.c index a9b7cbc37..77b8b56fc 100644 --- a/src/vdr/post_vdr.c +++ b/src/vdr/post_vdr.c @@ -22,8 +22,8 @@ * plugins for VDR */ -#include "xine_internal.h" -#include "post.h" +#include +#include #include "post_vdr.h" diff --git a/src/vdr/post_vdr_audio.c b/src/vdr/post_vdr_audio.c index 96fa84fb5..79015ec21 100644 --- a/src/vdr/post_vdr_audio.c +++ b/src/vdr/post_vdr_audio.c @@ -28,8 +28,8 @@ #define LOG */ -#include "xine_internal.h" -#include "post.h" +#include +#include #include "post_vdr.h" diff --git a/src/vdr/post_vdr_video.c b/src/vdr/post_vdr_video.c index ed0eafc35..8e66c8eb5 100644 --- a/src/vdr/post_vdr_video.c +++ b/src/vdr/post_vdr_video.c @@ -28,8 +28,8 @@ #define LOG */ -#include "xine_internal.h" -#include "post.h" +#include +#include #include "post_vdr.h" diff --git a/src/video_out/macosx/XineOpenGLView.m b/src/video_out/macosx/XineOpenGLView.m index a9ffee00f..5ed515704 100644 --- a/src/video_out/macosx/XineOpenGLView.m +++ b/src/video_out/macosx/XineOpenGLView.m @@ -30,11 +30,7 @@ #import "XineOpenGLView.h" -#ifdef XINE_COMPILE -# include "xineutils.h" -#else -# include -#endif +#include NSString *XineViewDidResizeNotification EXPORTED = @"XineViewDidResizeNotification"; diff --git a/src/video_out/video_out_aa.c b/src/video_out/video_out_aa.c index bcbe2477e..ff9abd320 100644 --- a/src/video_out/video_out_aa.c +++ b/src/video_out/video_out_aa.c @@ -38,9 +38,9 @@ #include #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" -#include "xineutils.h" +#include +#include +#include /* * global variables diff --git a/src/video_out/video_out_caca.c b/src/video_out/video_out_caca.c index 231befcdb..6b9f3756e 100644 --- a/src/video_out/video_out_caca.c +++ b/src/video_out/video_out_caca.c @@ -38,10 +38,10 @@ #include #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" +#include +#include #include "yuv2rgb.h" -#include "xineutils.h" +#include /* * structures diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c index 3445be127..39a7917ba 100644 --- a/src/video_out/video_out_directfb.c +++ b/src/video_out/video_out_directfb.c @@ -39,10 +39,10 @@ #define LOG_VERBOSE #include "xine.h" -#include "xine_internal.h" -#include "video_out.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include +#include +#include #ifdef DIRECTFB_X11 # include "x11osd.h" diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c index b70709856..c2b3aa101 100644 --- a/src/video_out/video_out_directx.c +++ b/src/video_out/video_out_directx.c @@ -35,10 +35,10 @@ typedef unsigned char boolean; */ #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" +#include +#include -#include "xine_internal.h" +#include #include "yuv2rgb.h" #define NEW_YUV 1 diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c index 859959455..4914548a1 100644 --- a/src/video_out/video_out_fb.c +++ b/src/video_out/video_out_fb.c @@ -55,7 +55,7 @@ #include #include "xine.h" -#include "video_out.h" +#include #include @@ -78,10 +78,10 @@ #define LOG */ -#include "xine_internal.h" +#include #include "yuv2rgb.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include typedef struct fb_frame_s { diff --git a/src/video_out/video_out_none.c b/src/video_out/video_out_none.c index c28b0334e..c23c828a6 100644 --- a/src/video_out/video_out_none.c +++ b/src/video_out/video_out_none.c @@ -33,10 +33,10 @@ #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include +#include +#include typedef struct { vo_frame_t vo_frame; diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c index 04413eb80..466aeda27 100644 --- a/src/video_out/video_out_opengl.c +++ b/src/video_out/video_out_opengl.c @@ -88,11 +88,11 @@ #endif #include "xine.h" -#include "video_out.h" +#include -#include "xine_internal.h" +#include #include "yuv2rgb.h" -#include "xineutils.h" +#include #include "x11osd.h" diff --git a/src/video_out/video_out_pgx32.c b/src/video_out/video_out_pgx32.c index 505a257ce..884f9939f 100644 --- a/src/video_out/video_out_pgx32.c +++ b/src/video_out/video_out_pgx32.c @@ -41,10 +41,10 @@ #include #include -#include "xine_internal.h" +#include #include "bswap.h" -#include "vo_scale.h" -#include "xineutils.h" +#include +#include /* gfxp register defines */ diff --git a/src/video_out/video_out_pgx64.c b/src/video_out/video_out_pgx64.c index 21dcdfb09..d0e74b1e3 100644 --- a/src/video_out/video_out_pgx64.c +++ b/src/video_out/video_out_pgx64.c @@ -43,10 +43,10 @@ #include #include -#include "xine_internal.h" +#include #include "bswap.h" -#include "vo_scale.h" -#include "xineutils.h" +#include +#include /* * The maximum number of frames that can be used in multi-buffering diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c index 6ee6b19bd..5866f822f 100644 --- a/src/video_out/video_out_sdl.c +++ b/src/video_out/video_out_sdl.c @@ -59,10 +59,10 @@ */ #include "xine.h" -#include "xine_internal.h" -#include "video_out.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include +#include +#include #ifdef HAVE_X11 #include diff --git a/src/video_out/video_out_stk.c b/src/video_out/video_out_stk.c index 45e9900fd..ba4687b08 100644 --- a/src/video_out/video_out_stk.c +++ b/src/video_out/video_out_stk.c @@ -59,10 +59,10 @@ */ #include "xine.h" -#include "xine_internal.h" -#include "video_out.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include +#include +#include /* Extend the video frame class with stk private data */ typedef struct stk_frame_s { diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index 013695c46..e6c3ffdf6 100644 --- a/src/video_out/video_out_syncfb.c +++ b/src/video_out/video_out_syncfb.c @@ -52,10 +52,10 @@ #include "video_out_syncfb.h" #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include +#include +#include /*#define DEBUG_OUTPUT*/ diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c index 3228bbdbb..251dac87e 100644 --- a/src/video_out/video_out_vidix.c +++ b/src/video_out/video_out_vidix.c @@ -57,10 +57,10 @@ #define LOG */ -#include "video_out.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include +#include +#include #ifdef HAVE_X11 #include "x11osd.h" diff --git a/src/video_out/video_out_xcbshm.c b/src/video_out/video_out_xcbshm.c index c6ad9e2f1..9e9df7a71 100644 --- a/src/video_out/video_out_xcbshm.c +++ b/src/video_out/video_out_xcbshm.c @@ -37,7 +37,7 @@ #include #include "xine.h" -#include "video_out.h" +#include #include @@ -56,10 +56,10 @@ #define LOG */ -#include "xine_internal.h" +#include #include "yuv2rgb.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include #include "xcbosd.h" typedef struct { diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c index 1b59f5691..dff973317 100644 --- a/src/video_out/video_out_xcbxv.c +++ b/src/video_out/video_out_xcbxv.c @@ -58,11 +58,11 @@ */ #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" +#include +#include /* #include "overlay.h" */ -#include "xineutils.h" -#include "vo_scale.h" +#include +#include #include "xcbosd.h" typedef struct xv_driver_s xv_driver_t; diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index ddcdb677c..52468781a 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -35,7 +35,7 @@ #include #include "xine.h" -#include "video_out.h" +#include #include #include @@ -57,10 +57,10 @@ #define LOG */ -#include "xine_internal.h" +#include #include "yuv2rgb.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include #include "x11osd.h" #define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \ diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index ab5410ac3..10e13ab3c 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -63,11 +63,11 @@ */ #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" +#include +#include /* #include "overlay.h" */ -#include "xineutils.h" -#include "vo_scale.h" +#include +#include #include "x11osd.h" #define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \ diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c index 2c913dc0e..91db684da 100644 --- a/src/video_out/video_out_xvmc.c +++ b/src/video_out/video_out_xvmc.c @@ -66,12 +66,12 @@ */ #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" +#include +#include #include "accel_xvmc.h" -#include "xineutils.h" -#include "vo_scale.h" +#include +#include /* #define LOG1 */ /* #define DLOG */ diff --git a/src/video_out/x11osd.c b/src/video_out/x11osd.c index e0cb6f1f6..450812f90 100644 --- a/src/video_out/x11osd.c +++ b/src/video_out/x11osd.c @@ -51,7 +51,7 @@ #define LOG */ -#include "xine_internal.h" +#include #include "x11osd.h" struct x11osd diff --git a/src/video_out/x11osd.h b/src/video_out/x11osd.h index fe0bf6208..0ffd6fba6 100644 --- a/src/video_out/x11osd.h +++ b/src/video_out/x11osd.h @@ -28,7 +28,7 @@ #ifndef X11OSD_H #define X11OSD_H -#include "vo_scale.h" +#include typedef struct x11osd x11osd; enum x11osd_mode {X11OSD_SHAPED, X11OSD_COLORKEY}; diff --git a/src/video_out/xcbosd.c b/src/video_out/xcbosd.c index 4bb2b60af..8bb96be1e 100644 --- a/src/video_out/xcbosd.c +++ b/src/video_out/xcbosd.c @@ -49,7 +49,7 @@ #define LOG */ -#include "xine_internal.h" +#include #include "xcbosd.h" struct xcbosd diff --git a/src/video_out/xcbosd.h b/src/video_out/xcbosd.h index 32af4965e..1d4fd1c3a 100644 --- a/src/video_out/xcbosd.h +++ b/src/video_out/xcbosd.h @@ -29,7 +29,7 @@ #ifndef XCBOSD_H #define XCBOSD_H -#include "vo_scale.h" +#include typedef struct xcbosd xcbosd; enum xcbosd_mode {XCBOSD_SHAPED, XCBOSD_COLORKEY}; diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h index 84964af17..d6cd7e514 100644 --- a/src/video_out/xxmc.h +++ b/src/video_out/xxmc.h @@ -83,9 +83,9 @@ */ #include "xine.h" -#include "video_out.h" -#include "xine_internal.h" -#include "xineutils.h" +#include +#include +#include #include "vo_scale.h" #include "x11osd.h" #include "accel_xvmc.h" diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c index 0ca6537a7..f1ad4dba8 100644 --- a/src/video_out/yuv2rgb.c +++ b/src/video_out/yuv2rgb.c @@ -39,7 +39,7 @@ #define LOG */ -#include "xineutils.h" +#include static int prof_scale_line = -1; diff --git a/src/video_out/yuv2rgb_mlib.c b/src/video_out/yuv2rgb_mlib.c index 8635526ed..794ce437e 100644 --- a/src/video_out/yuv2rgb_mlib.c +++ b/src/video_out/yuv2rgb_mlib.c @@ -34,8 +34,8 @@ #include #include -#include "attributes.h" -#include "xineutils.h" +#include +#include #include "yuv2rgb.h" #define MIN(a, b) (((a) < (b)) ? (a) : (b)) diff --git a/src/video_out/yuv2rgb_mmx.c b/src/video_out/yuv2rgb_mmx.c index 20a9b5a00..1835efe68 100644 --- a/src/video_out/yuv2rgb_mmx.c +++ b/src/video_out/yuv2rgb_mmx.c @@ -32,7 +32,7 @@ #include #include "yuv2rgb.h" -#include "xineutils.h" +#include #define CPU_MMXEXT 0 #define CPU_MMX 1 diff --git a/src/xine-engine/alphablend.c b/src/xine-engine/alphablend.c index 4dffa09ad..c47257273 100644 --- a/src/xine-engine/alphablend.c +++ b/src/xine-engine/alphablend.c @@ -32,9 +32,9 @@ #include #include -#include "xine_internal.h" -#include "video_out.h" -#include "alphablend.h" +#include +#include +#include #include "bswap.h" diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index 5476262d9..6a0688f0d 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.c @@ -39,8 +39,8 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include static void *audio_decoder_loop (void *stream_gen) { diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index aac1739aa..39e3cd1a4 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -89,11 +89,11 @@ #define LOG_RESAMPLE_SYNC 0 -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" -#include "resample.h" -#include "metronom.h" +#include +#include +#include +#include +#include #define NUM_AUDIO_BUFFERS 32 diff --git a/src/xine-engine/broadcaster.c b/src/xine-engine/broadcaster.c index ce7494c1d..71d466c3a 100644 --- a/src/xine-engine/broadcaster.c +++ b/src/xine-engine/broadcaster.c @@ -57,9 +57,9 @@ #include #include -#include "xine_internal.h" -#include "buffer.h" -#include "xineutils.h" +#include +#include +#include #define QLEN 5 /* maximum connection queue length */ #define _BUFSIZ 512 diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c index 93ad75ba0..8b8a8334a 100644 --- a/src/xine-engine/buffer.c +++ b/src/xine-engine/buffer.c @@ -43,9 +43,9 @@ #define LOG */ -#include "buffer.h" -#include "xineutils.h" -#include "xine_internal.h" +#include +#include +#include /* * put a previously allocated buffer element back into the buffer pool diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c index eece2df90..08ff194fa 100644 --- a/src/xine-engine/buffer_types.c +++ b/src/xine-engine/buffer_types.c @@ -32,7 +32,7 @@ #include #include #include -#include "buffer.h" +#include #include "bswap.h" typedef struct video_db_s { diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 2f5e6214a..47b77b03e 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -31,7 +31,7 @@ #include #include #include -#include "configfile.h" +#include #define LOG_MODULE "configfile" #define LOG_VERBOSE @@ -39,8 +39,8 @@ #define LOG */ -#include "xineutils.h" -#include "xine_internal.h" +#include +#include static const xine_config_entry_translation_t *config_entry_translation_user = NULL; static const xine_config_entry_translation_t config_entry_translation[] = { diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index 5010c60eb..232e0342e 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -39,9 +39,9 @@ #define LOG */ -#include "xine_internal.h" -#include "demuxers/demux.h" -#include "buffer.h" +#include +#include +#include #ifdef WIN32 #include diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index f79187682..bf0d88fae 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -26,7 +26,7 @@ #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" +#include xine_event_t *xine_event_get (xine_event_queue_t *queue) { diff --git a/src/xine-engine/info_helper.c b/src/xine-engine/info_helper.c index 1ac4ed982..bc66ba24e 100644 --- a/src/xine-engine/info_helper.c +++ b/src/xine-engine/info_helper.c @@ -35,7 +35,7 @@ #define XINE_ENGINE_INTERNAL -#include "info_helper.h" +#include /* ******************* Stream Info *************************** */ diff --git a/src/xine-engine/input_cache.c b/src/xine-engine/input_cache.c index 0535bc8f7..2989d8718 100644 --- a/src/xine-engine/input_cache.c +++ b/src/xine-engine/input_cache.c @@ -33,7 +33,7 @@ #define LOG */ -#include "xine_internal.h" +#include #include #define DEFAULT_BUFFER_SIZE 1024 diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c index a8268552a..e7ef356b3 100644 --- a/src/xine-engine/input_rip.c +++ b/src/xine-engine/input_rip.c @@ -64,7 +64,7 @@ # define CLR_RST "\e[0;39m" #endif -#include "xine_internal.h" +#include #ifndef HAVE_FSEEKO # define fseeko fseek diff --git a/src/xine-engine/io_helper.c b/src/xine-engine/io_helper.c index b51442402..d51feb4c6 100644 --- a/src/xine-engine/io_helper.c +++ b/src/xine-engine/io_helper.c @@ -38,7 +38,7 @@ #define XINE_ENGINE_INTERNAL -#include "io_helper.h" +#include /* private constants */ #define XIO_FILE_READ 0 diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index a03ea6d17..7a6237b79 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.c @@ -51,17 +51,17 @@ #define XINE_ENABLE_EXPERIMENTAL_FEATURES 1 #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" -#include "xine_plugin.h" -#include "plugin_catalog.h" -#include "demuxers/demux.h" -#include "input/input_plugin.h" -#include "video_out.h" -#include "post.h" -#include "metronom.h" -#include "configfile.h" -#include "xineutils.h" -#include "compat.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #if 0 diff --git a/src/xine-engine/lrb.c b/src/xine-engine/lrb.c index 6da846a7c..a2fc5d1da 100644 --- a/src/xine-engine/lrb.c +++ b/src/xine-engine/lrb.c @@ -23,7 +23,7 @@ #endif #include "lrb.h" -#include "xineutils.h" +#include lrb_t *lrb_new (int max_num_entries, fifo_buffer_t *fifo) { diff --git a/src/xine-engine/lrb.h b/src/xine-engine/lrb.h index 491ae8843..0f524b7eb 100644 --- a/src/xine-engine/lrb.h +++ b/src/xine-engine/lrb.h @@ -24,11 +24,7 @@ #ifndef HAVE_LRB_H #define HAVE_LRB_H -#ifdef XINE_COMPILE -# include "buffer.h" -#else -# include -#endif +#include typedef struct { diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index e9bd86836..42aed4e76 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -40,9 +40,9 @@ #define METRONOM_INTERNAL #define METRONOM_CLOCK_INTERNAL -#include "xine_internal.h" -#include "metronom.h" -#include "xineutils.h" +#include +#include +#include #define MAX_AUDIO_DELTA 1600 #define AUDIO_SAMPLE_NUM 32768 diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 1587b76e4..39687e83f 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -50,11 +50,11 @@ #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" +#include #include "xine-engine/bswap.h" -#include "xineutils.h" -#include "video_out.h" -#include "osd.h" +#include +#include +#include #ifdef HAVE_FT2 #include diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c index e54d2234f..e057ff99f 100644 --- a/src/xine-engine/post.c +++ b/src/xine-engine/post.c @@ -25,7 +25,7 @@ #define POST_INTERNAL #define XINE_ENGINE_INTERNAL -#include "post.h" +#include #include diff --git a/src/xine-engine/refcounter.c b/src/xine-engine/refcounter.c index 539abf3ed..4bb6a0351 100644 --- a/src/xine-engine/refcounter.c +++ b/src/xine-engine/refcounter.c @@ -23,8 +23,8 @@ #define LOG */ -#include "xine_internal.h" -#include "refcounter.h" +#include +#include refcounter_t* _x_new_refcounter(void *object, void (*destructor)(void *)) { diff --git a/src/xine-engine/resample.c b/src/xine-engine/resample.c index 43911c401..f907c965e 100644 --- a/src/xine-engine/resample.c +++ b/src/xine-engine/resample.c @@ -24,8 +24,8 @@ #include #include -#include "attributes.h" -#include "resample.h" +#include +#include /* contributed by paul flinders */ diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c index 8f9021aa1..7376a3f9e 100644 --- a/src/xine-engine/scratch.c +++ b/src/xine-engine/scratch.c @@ -33,8 +33,8 @@ #define LOG */ -#include "xineutils.h" -#include "scratch.h" +#include +#include static void __attribute__((__format__(__printf__, 2, 0))) scratch_printf (scratch_buffer_t *this, const char *format, va_list argp) diff --git a/src/xine-engine/spu.c b/src/xine-engine/spu.c index 813300fb0..c610a43c9 100644 --- a/src/xine-engine/spu.c +++ b/src/xine-engine/spu.c @@ -19,8 +19,8 @@ * */ -#include "xine_internal.h" -#include "spu.h" +#include +#include #define BLACK_OPACITY 67 #define COLOUR_OPACITY 100 diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index c88e01714..ca6e7aa23 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -35,8 +35,8 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include +#include #include #define SPU_SLEEP_INTERVAL (90000/2) diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 8c9810da1..0bab612ce 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -44,10 +44,10 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" -#include "metronom.h" -#include "xineutils.h" +#include +#include +#include +#include #define NUM_FRAME_BUFFERS 15 #define MAX_USEC_TO_SLEEP 20000 diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c index c189fa56b..44080c469 100644 --- a/src/xine-engine/video_overlay.c +++ b/src/xine-engine/video_overlay.c @@ -25,11 +25,11 @@ #include #include -#include "buffer.h" -#include "xine_internal.h" +#include +#include #include "bswap.h" -#include "xineutils.h" -#include "video_overlay.h" +#include +#include /* #define LOG_DEBUG diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c index ff30c47a6..5da5ab26e 100644 --- a/src/xine-engine/vo_scale.c +++ b/src/xine-engine/vo_scale.c @@ -32,8 +32,8 @@ #define LOG */ -#include "xine_internal.h" -#include "vo_scale.h" +#include +#include /* * convert delivered height/width to ideal width/height diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 6d6e05b19..ec2dc9170 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -58,21 +58,21 @@ #define XINE_ENGINE_INTERNAL #define METRONOM_CLOCK_INTERNAL -#include "xine_internal.h" -#include "plugin_catalog.h" -#include "audio_out.h" -#include "video_out.h" -#include "demuxers/demux.h" -#include "buffer.h" -#include "spu_decoder.h" -#include "input/input_plugin.h" -#include "metronom.h" -#include "configfile.h" -#include "osd.h" -#include "spu.h" - -#include "xineutils.h" -#include "compat.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #ifdef WIN32 # include diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c index 7913a18d6..32b8663a6 100644 --- a/src/xine-engine/xine_interface.c +++ b/src/xine-engine/xine_interface.c @@ -40,11 +40,11 @@ #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" -#include "audio_out.h" -#include "video_out.h" -#include "demuxers/demux.h" -#include "post.h" +#include +#include +#include +#include +#include /* * version information / checking diff --git a/src/xine-utils/array.c b/src/xine-utils/array.c index f6989fbb6..0db45be0c 100644 --- a/src/xine-utils/array.c +++ b/src/xine-utils/array.c @@ -23,8 +23,8 @@ #include #include -#include "attributes.h" -#include "array.h" +#include +#include #define MIN_CHUNK_SIZE 32 diff --git a/src/xine-utils/color.c b/src/xine-utils/color.c index 0b9cf0188..dc2c7e5e5 100644 --- a/src/xine-utils/color.c +++ b/src/xine-utils/color.c @@ -62,7 +62,7 @@ * instructions. */ -#include "xine_internal.h" +#include /* * In search of the perfect colorspace conversion formulae... diff --git a/src/xine-utils/copy.c b/src/xine-utils/copy.c index ed42b3a88..500b6db73 100644 --- a/src/xine-utils/copy.c +++ b/src/xine-utils/copy.c @@ -25,7 +25,7 @@ #include "config.h" #endif -#include "xineutils.h" +#include void yv12_to_yv12 (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dst, int y_dst_pitch, diff --git a/src/xine-utils/cpu_accel.c b/src/xine-utils/cpu_accel.c index 8bad23db9..07978b55f 100644 --- a/src/xine-utils/cpu_accel.c +++ b/src/xine-utils/cpu_accel.c @@ -39,7 +39,7 @@ #define LOG */ -#include "xineutils.h" +#include #if defined(__i386__) || defined(__x86_64__) diff --git a/src/xine-utils/crc.c b/src/xine-utils/crc.c index ba0e3010b..4f720e9cc 100644 --- a/src/xine-utils/crc.c +++ b/src/xine-utils/crc.c @@ -20,7 +20,7 @@ * Common CRC calculation code. */ -#include "xineutils.h" +#include static const uint32_t crc32_table[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, diff --git a/src/xine-utils/list.c b/src/xine-utils/list.c index 65bdaec26..7a2b521bd 100644 --- a/src/xine-utils/list.c +++ b/src/xine-utils/list.c @@ -23,8 +23,8 @@ #endif #include -#include "attributes.h" -#include "list.h" +#include +#include #define MIN_CHUNK_SIZE 32 #define MAX_CHUNK_SIZE 65536 diff --git a/src/xine-utils/memcpy.c b/src/xine-utils/memcpy.c index da4b83b09..15b0b228b 100644 --- a/src/xine-utils/memcpy.c +++ b/src/xine-utils/memcpy.c @@ -50,7 +50,7 @@ #define LOG */ -#include "xine_internal.h" +#include void *(* xine_fast_memcpy)(void *to, const void *from, size_t len); diff --git a/src/xine-utils/monitor.c b/src/xine-utils/monitor.c index 3c7c3e10a..8cbfdaa72 100644 --- a/src/xine-utils/monitor.c +++ b/src/xine-utils/monitor.c @@ -26,7 +26,7 @@ #include #include -#include "xineutils.h" +#include #define MAX_ID 10 diff --git a/src/xine-utils/pool.c b/src/xine-utils/pool.c index a1fddadd9..60330ef53 100644 --- a/src/xine-utils/pool.c +++ b/src/xine-utils/pool.c @@ -22,9 +22,9 @@ #endif #include -#include "attributes.h" -#include "pool.h" -#include "array.h" +#include +#include +#include #define MIN_CHUNK_SIZE 32 #define MAX_CHUNK_SIZE 65536 diff --git a/src/xine-utils/ring_buffer.c b/src/xine-utils/ring_buffer.c index 031fda4fc..7042eaa68 100644 --- a/src/xine-utils/ring_buffer.c +++ b/src/xine-utils/ring_buffer.c @@ -27,10 +27,10 @@ #include #include #include -#include "attributes.h" -#include "pool.h" -#include "list.h" -#include "ring_buffer.h" +#include +#include +#include +#include #define RING_BUFFER_EXTRA_BUFFER_SIZE (1024 * 8) diff --git a/src/xine-utils/sorted_array.c b/src/xine-utils/sorted_array.c index 363325f0b..9dbe1fd0e 100644 --- a/src/xine-utils/sorted_array.c +++ b/src/xine-utils/sorted_array.c @@ -23,8 +23,8 @@ #include #include -#include "attributes.h" -#include "sorted_array.h" +#include +#include /* Array internal struct */ struct xine_sarray_s { diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c index d9eb7fb3f..5aff537b4 100644 --- a/src/xine-utils/utils.c +++ b/src/xine-utils/utils.c @@ -27,10 +27,10 @@ #include "config.h" #endif -#include "xineutils.h" -#include "xineintl.h" +#include +#include #ifdef _MSC_VER -#include "xine_internal.h" +#include #endif #include diff --git a/src/xine-utils/xine_buffer.c b/src/xine-utils/xine_buffer.c index 190ab5197..3891aec11 100644 --- a/src/xine-utils/xine_buffer.c +++ b/src/xine-utils/xine_buffer.c @@ -58,7 +58,7 @@ #define LOG */ -#include "xineutils.h" +#include #define CHECKS diff --git a/src/xine-utils/xine_check.c b/src/xine-utils/xine_check.c index f00a23832..e850f9f48 100644 --- a/src/xine-utils/xine_check.c +++ b/src/xine-utils/xine_check.c @@ -45,7 +45,7 @@ #include #include "xine_check.h" -#include "xineutils.h" +#include #if defined(__linux__) diff --git a/src/xine-utils/xine_check.h b/src/xine-utils/xine_check.h index 4b21bf74e..75eda102d 100644 --- a/src/xine-utils/xine_check.h +++ b/src/xine-utils/xine_check.h @@ -2,11 +2,7 @@ #define XINE_CHECK_H #include -#ifdef XINE_COMPILE -# include "xine.h" -#else -# include -#endif +#include /* * Start checking xine setup here diff --git a/src/xine-utils/xine_mutex.c b/src/xine-utils/xine_mutex.c index c94f32be0..52d17d8e5 100644 --- a/src/xine-utils/xine_mutex.c +++ b/src/xine-utils/xine_mutex.c @@ -24,7 +24,7 @@ #include #include -#include "xineutils.h" +#include /* #define DBG_MUTEX diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c index bb03e5a79..e276beef0 100644 --- a/src/xine-utils/xmllexer.c +++ b/src/xine-utils/xmllexer.c @@ -26,12 +26,12 @@ */ #ifdef XINE_COMPILE -#include "xineutils.h" +#include #else #define lprintf(...) #define xine_xmalloc malloc #endif -#include "xmllexer.h" +#include #include #include #include diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index a7bc146a9..1213072f3 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -37,13 +37,13 @@ */ #ifdef XINE_COMPILE -#include "xineutils.h" +#include #else #define lprintf(...) #define xine_xmalloc malloc #endif -#include "xmllexer.h" -#include "xmlparser.h" +#include +#include #define TOKEN_SIZE 4 * 1024 -- cgit v1.2.3 From 916fbee057ef45a6b7b9dbee93784b16820f6b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 03:00:29 +0100 Subject: Rename spu.c and spu.h to spudec.c and spudec.h to avoid confusing the two source and header files. --HG-- rename : src/libspudec/spu.c => src/libspudec/spudec.c rename : src/libspudec/spu.h => src/libspudec/spudec.h --- src/libspudec/Makefile.am | 4 +- src/libspudec/spu.c | 1026 -------------------------------------- src/libspudec/spu.h | 142 ------ src/libspudec/spudec.c | 1026 ++++++++++++++++++++++++++++++++++++++ src/libspudec/spudec.h | 142 ++++++ src/libspudec/xine_spu_decoder.c | 3 +- 6 files changed, 1172 insertions(+), 1171 deletions(-) delete mode 100644 src/libspudec/spu.c delete mode 100644 src/libspudec/spu.h create mode 100644 src/libspudec/spudec.c create mode 100644 src/libspudec/spudec.h (limited to 'src') diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am index 62de3774d..337428652 100644 --- a/src/libspudec/Makefile.am +++ b/src/libspudec/Makefile.am @@ -4,7 +4,7 @@ AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav AM_LDFLAGS = $(xineplug_ldflags) -noinst_HEADERS = spu.h +noinst_HEADERS = spudec.h xineplug_LTLIBRARIES = xineplug_decode_spu.la @@ -16,6 +16,6 @@ external_dvdnav_libs = internal_dvdnav_sources = nav_read.c endif -xineplug_decode_spu_la_SOURCES = $(internal_dvdnav_sources) spu.c xine_spu_decoder.c +xineplug_decode_spu_la_SOURCES = $(internal_dvdnav_sources) spudec.c xine_spu_decoder.c xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(external_dvdnav_libs) $(PTHREAD_LIBS) xineplug_decode_spu_la_CFLAGS = $(AM_CFLAGS) $(DVDNAV_CFLAGS) diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c deleted file mode 100644 index c836dbf58..000000000 --- a/src/libspudec/spu.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Copyright (C) 2002-2004 the xine project - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * spu.c - converts DVD subtitles to an XPM image - * - * Mostly based on hard work by: - * - * Copyright (C) 2000 Samuel Hocevar - * and Michel Lespinasse - * - * Lots of rearranging by: - * Aaron Holtzman - * Thomas Mirlacher - * implemented reassembling - * cleaner implementation of SPU are saving - * overlaying (proof of concept for now) - * ... and yes, it works now with oms - * added tranparency (provided by the SPU hdr) - * changed structures for easy porting to MGAs DVD mode - * This file is part of xine - * This file was originally part of the OMS program. - * - * This program 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, or (at your option) - * any later version. - * - * This program 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "spu.h" -#include -#include "xine-engine/bswap.h" -#ifdef HAVE_DVDNAV -# include -# include -#else -# include "nav_read.h" -# include "nav_print.h" -#endif - - -/* -#define LOG_DEBUG 1 -#define LOG_BUTTON 1 -#define LOG_NAV 1 -*/ - -static void spudec_do_commands (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); -static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); -static void spudec_discover_clut (xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl); -#ifdef LOG_DEBUG -static void spudec_print_overlay( vo_overlay_t *overlay ); -#endif - -void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) { - uint8_t *p; - uint32_t packet_len; - uint32_t stream_id; - uint32_t header_len; - pci_t pci; - dsi_t dsi; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - - p = buf->content; - if (p[0] || p[1] || (p[2] != 1)) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec:spudec_decode_nav:nav demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); - return; - } - - packet_len = p[4] << 8 | p[5]; - stream_id = p[3]; - - header_len = 6; - p += header_len; - - if (stream_id == 0xbf) { /* Private stream 2 */ -/* int i; - * for(i=0;i<80;i++) { - * printf("%02x ",p[i]); - * } - * printf("\n p[0]=0x%02x\n",p[0]); - */ - if(p[0] == 0x00) { -#ifdef LOG_NAV - printf("libspudec:nav_PCI\n"); -#endif - navRead_PCI(&pci, p+1); -#ifdef LOG_NAV - printf("libspudec:nav:hli_ss=%u, hli_s_ptm=%u, hli_e_ptm=%u, btn_sl_e_ptm=%u pts=%lli\n", - pci.hli.hl_gi.hli_ss, - pci.hli.hl_gi.hli_s_ptm, - pci.hli.hl_gi.hli_e_ptm, - pci.hli.hl_gi.btn_se_e_ptm, - buf->pts); - printf("libspudec:nav:btn_sn/ofn=%u, btn_ns=%u, fosl_btnn=%u, foac_btnn=%u\n", - pci.hli.hl_gi.btn_ofn, pci.hli.hl_gi.btn_ns, - pci.hli.hl_gi.fosl_btnn, pci.hli.hl_gi.foac_btnn); - printf("btngr_ns %d\n", pci.hli.hl_gi.btngr_ns); - printf("btngr%d_dsp_ty 0x%02x\n", 1, pci.hli.hl_gi.btngr1_dsp_ty); - printf("btngr%d_dsp_ty 0x%02x\n", 2, pci.hli.hl_gi.btngr2_dsp_ty); - printf("btngr%d_dsp_ty 0x%02x\n", 3, pci.hli.hl_gi.btngr3_dsp_ty); - //navPrint_PCI(&pci); - //navPrint_PCI_GI(&pci.pci_gi); - //navPrint_NSML_AGLI(&pci.nsml_agli); - //navPrint_HLI(&pci.hli); - //navPrint_HL_GI(&pci.hli.hl_gi, & btngr_ns, & btn_ns); -#endif - } - - p += packet_len; - - /* We should now have a DSI packet. */ - /* We don't need anything from the DSI packet here. */ - if(p[6] == 0x01) { - packet_len = p[4] << 8 | p[5]; - p += 6; -#ifdef LOG_NAV - printf("NAV DSI packet\n"); -#endif - navRead_DSI(&dsi, p+1); - -// self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; -// self->vobu_length = self->dsi.dsi_gi.vobu_ea; - } - } - - /* NAV packets contain start and end presentation timestamps, which tell the - * application, when the highlight information in the NAV is supposed to be valid. - * We handle these timestamps only in a very stripped-down way: We keep a list - * of NAV packets (or better: the PCI part of them), tagged with a VPTS timestamp - * telling, when the NAV should be processed. However, we only enqueue a new node - * into this list, when we receive new highlight information during an already - * showing menu. This happens very rarerly on common DVDs, so it is of low impact. - * And we only check for processing of queued entries at some prominent - * locations in this SPU decoder. Since presentation timestamps rarely solve a real - * purpose on most DVDs, this is ok compared to the full-blown solution, which would - * require a separate thread managing the queue all the time. */ - pthread_mutex_lock(&this->nav_pci_lock); - switch (pci.hli.hl_gi.hli_ss) { - case 0: - /* No Highlight information for this VOBU */ - if ( this->pci_cur.pci.hli.hl_gi.hli_ss == 1) { - /* Hide menu spu between menus */ -#ifdef LOG_BUTTON - printf("libspudec:nav:SHOULD HIDE SPU here\n"); -#endif - if( this->menu_handle < 0 ) { - this->menu_handle = ovl_manager->get_handle(ovl_manager,1); - } - if( this->menu_handle >= 0 ) { - this->event.object.handle = this->menu_handle; - this->event.event_type = OVERLAY_EVENT_HIDE; - /* hide menu right now */ - this->event.vpts = 0; - ovl_manager->add_event(ovl_manager, (void *)&this->event); - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: No video_overlay handles left for menu\n"); - } - } - spudec_clear_nav_list(this); - xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); - /* incoming SPUs will be plain subtitles */ - this->event.object.object_type = 0; - if (this->button_filter) { - /* we possibly had buttons before, so we update the UI info */ - xine_event_t event; - xine_ui_data_t data; - - event.type = XINE_EVENT_UI_NUM_BUTTONS; - event.data = &data; - event.data_length = sizeof(data); - data.num_buttons = 0; - - xine_event_send(this->stream, &event); - } - this->button_filter=0; - - break; - case 1: - /* All New Highlight information for this VOBU */ - if (this->pci_cur.pci.hli.hl_gi.hli_ss != 0 && - pci.hli.hl_gi.hli_s_ptm > this->pci_cur.pci.hli.hl_gi.hli_s_ptm) { - pci_node_t *node = &this->pci_cur; -#ifdef LOG_DEBUG - printf("libspudec: allocating new PCI node for hli_s_ptm %d\n", pci.hli.hl_gi.hli_s_ptm); -#endif - /* append PCI at the end of the list */ - while (node->next) node = node->next; - node->next = (pci_node_t *)xine_xmalloc(sizeof(pci_node_t)); - node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm); - node->next->next = NULL; - xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t)); - } else { - spudec_clear_nav_list(this); - /* menu ahead, remember PCI for later use */ - xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); - spudec_process_nav(this); - } - break; - case 2: - /* Use Highlight information from previous VOBU */ - if (this->pci_cur.next) { - /* apply changes to last enqueued NAV */ - pci_node_t *node = this->pci_cur.next; - while (node->next) node = node->next; - node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - spudec_update_nav(this); - } else { - this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - } - break; - case 3: - /* Use Highlight information from previous VOBU except commands, which come from this VOBU */ - if (this->pci_cur.next) { - /* apply changes to last enqueued NAV */ - pci_node_t *node = this->pci_cur.next; - while (node->next) node = node->next; - node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - /* FIXME: Add command copying here */ - spudec_update_nav(this); - } else { - this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - /* FIXME: Add command copying here */ - } - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec: unknown pci.hli.hl_gi.hli_ss = %d\n", pci.hli.hl_gi.hli_ss ); - break; - } - pthread_mutex_unlock(&this->nav_pci_lock); - return; -} - -void spudec_clear_nav_list(spudec_decoder_t *this) -{ - while (this->pci_cur.next) { - pci_node_t *node = this->pci_cur.next->next; - free(this->pci_cur.next); - this->pci_cur.next = node; - } - /* invalidate current timestamp */ - this->pci_cur.pci.hli.hl_gi.hli_s_ptm = (uint32_t)-1; -} - -void spudec_update_nav(spudec_decoder_t *this) -{ - metronom_clock_t *clock = this->stream->xine->clock; - - if (this->pci_cur.next && this->pci_cur.next->vpts <= clock->get_current_time(clock)) { - pci_node_t *node = this->pci_cur.next; - xine_fast_memcpy(&this->pci_cur, this->pci_cur.next, sizeof(pci_node_t)); - spudec_process_nav(this); - free(node); - } -} - -void spudec_process_nav(spudec_decoder_t *this) -{ - /* incoming SPUs will be menus */ - this->event.object.object_type = 1; - if (!this->button_filter) { - /* we possibly entered a menu, so we update the UI button info */ - xine_event_t event; - xine_ui_data_t data; - - event.type = XINE_EVENT_UI_NUM_BUTTONS; - event.data = &data; - event.data_length = sizeof(data); - data.num_buttons = this->pci_cur.pci.hli.hl_gi.btn_ns; - - xine_event_send(this->stream, &event); - } - this->button_filter=1; -} - -void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len) -{ -#ifdef LOG_DEBUG - printf ("libspudec: seq->complete = %d\n", seq->complete); - printf("libspudec:1: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", - seq->ra_offs, - seq->seq_len, - seq->buf_len, - seq->buf); -#endif - if (seq->complete) { - seq->seq_len = (((uint32_t)pkt_data[0])<<8) | pkt_data[1]; - seq->cmd_offs = (((uint32_t)pkt_data[2])<<8) | pkt_data[3]; - if (seq->cmd_offs >= seq->seq_len) { - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); - seq->broken = 1; - } - if (seq->buf_len < seq->seq_len) { - seq->buf_len = seq->seq_len; -#ifdef LOG_DEBUG - printf ("spu: MALLOC1: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); -#endif - if (seq->buf) { - free(seq->buf); - seq->buf = NULL; - } - seq->buf = malloc(seq->buf_len); -#ifdef LOG_DEBUG - printf ("spu: MALLOC2: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); -#endif - - } - seq->ra_offs = 0; - -#ifdef LOG_DEBUG - printf ("spu: buf_len: %d\n", seq->buf_len); - printf ("spu: cmd_off: %d\n", seq->cmd_offs); -#endif - } - -#ifdef LOG_DEBUG - printf("libspudec:2: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", - seq->ra_offs, - seq->seq_len, - seq->buf_len, - seq->buf); -#endif - if (seq->ra_offs < seq->seq_len) { - if (seq->ra_offs + pkt_len > seq->seq_len) - pkt_len = seq->seq_len - seq->ra_offs; - memcpy (seq->buf + seq->ra_offs, pkt_data, pkt_len); - seq->ra_offs += pkt_len; - } else { - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); - seq->broken = 1; - } - - if (seq->ra_offs == seq->seq_len) { - seq->finished = 0; - seq->complete = 1; - return; /* sequence ready */ - } - seq->complete = 0; - return; -} - -void spudec_process (spudec_decoder_t *this, int stream_id) { - spudec_seq_t *cur_seq; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - int pending = 1; - cur_seq = &this->spudec_stream_state[stream_id].ra_seq; - -#ifdef LOG_DEBUG - printf ("spu: Found SPU from stream %d pts=%lli vpts=%lli\n",stream_id, - this->spudec_stream_state[stream_id].pts, - this->spudec_stream_state[stream_id].vpts); -#endif - this->state.cmd_ptr = cur_seq->buf + cur_seq->cmd_offs; - this->state.modified = 1; /* Only draw picture if = 1 on first event of SPU */ - this->state.visible = OVERLAY_EVENT_SHOW; - this->state.forced_display = 0; /* 0 - No value, 1 - Forced Display. */ - this->state.delay = 0; - cur_seq->finished=0; - - do { - if (!(cur_seq->finished) ) { - pci_node_t *node; - - /* spu_channel is now set based on whether we are in the menu or not. */ - /* Bit 7 is set if only forced display SPUs should be shown */ - if ( (this->stream->spu_channel & 0x1f) != stream_id ) { -#ifdef LOG_DEBUG - printf ("spu: Dropping SPU channel %d. Not selected stream_id\n", stream_id); -#endif - return; - } - /* parse SPU command sequence, this will update forced_display, so it must come - * before the check for it */ - spudec_do_commands(this->stream->xine, &this->state, cur_seq, &this->overlay); - /* FIXME: Check for Forced-display or subtitle stream - * For subtitles, open event. - * For menus, store it for later. - */ - if (cur_seq->broken) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); - cur_seq->broken = 0; - return; - } - if ( (this->state.forced_display == 0) && (this->stream->spu_channel & 0x80) ) { -#ifdef LOG_DEBUG - printf ("spu: Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id); -#endif - return; - } - -#ifdef LOG_DEBUG - spudec_print_overlay( &this->overlay ); - printf ("spu: forced display:%s\n", this->state.forced_display ? "Yes" : "No" ); -#endif - pthread_mutex_lock(&this->nav_pci_lock); - /* search for a PCI that matches this SPU's PTS */ - for (node = &this->pci_cur; node; node = node->next) - if (node->pci.hli.hl_gi.hli_s_ptm == this->spudec_stream_state[stream_id].pts) - break; - if (node) { - if (this->state.visible == OVERLAY_EVENT_HIDE) { - /* menus are hidden via nav packet decoding, not here */ - /* FIXME: James is not sure about this solution and may want to look this over. - * I'm commiting it, because I haven't found a disc it breaks, but it fixes - * some instead. Michael Roitzsch */ - pthread_mutex_unlock(&this->nav_pci_lock); - continue; - } - if (node->pci.hli.hl_gi.fosl_btnn > 0) { - xine_event_t event; - - this->buttonN = node->pci.hli.hl_gi.fosl_btnn; - event.type = XINE_EVENT_INPUT_BUTTON_FORCE; - event.stream = this->stream; - event.data = &this->buttonN; - event.data_length = sizeof(this->buttonN); - xine_event_send(this->stream, &event); - } -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec:Full Overlay\n"); -#endif - if (!spudec_copy_nav_to_overlay(this->stream->xine, - &node->pci, this->state.clut, - this->buttonN, 0, &this->overlay, &this->overlay)) { - /* current button does not exist -> use another one */ - xine_event_t event; - - if (this->buttonN > node->pci.hli.hl_gi.btn_ns) - this->buttonN = node->pci.hli.hl_gi.btn_ns; - else - this->buttonN = 1; - event.type = XINE_EVENT_INPUT_BUTTON_FORCE; - event.stream = this->stream; - event.data = &this->buttonN; - event.data_length = sizeof(this->buttonN); - xine_event_send(this->stream, &event); - spudec_copy_nav_to_overlay(this->stream->xine, - &node->pci, this->state.clut, - this->buttonN, 0, &this->overlay, &this->overlay); - } - } else { - /* Subtitle and not a menu button */ - int i; - for (i = 0;i < 4; i++) { - this->overlay.hili_color[i] = this->overlay.color[i]; - this->overlay.hili_trans[i] = this->overlay.trans[i]; - } - } - pthread_mutex_unlock(&this->nav_pci_lock); - - if ((this->state.modified) ) { - spudec_draw_picture(this->stream->xine, &this->state, cur_seq, &this->overlay); - } - - if (this->state.need_clut) { - spudec_discover_clut(this->stream->xine, &this->state, &this->overlay); - } - - if (this->state.vobsub) { - int width, height; - int64_t duration; - - /* - * vobsubs are usually played with a scaled-down stream (not full DVD - * resolution), therefore we should try to realign it. - */ - - this->stream->video_out->status(this->stream->video_out, NULL, - &width, &height, &duration ); - - this->overlay.x = (width - this->overlay.width) / 2; - this->overlay.y = height - this->overlay.height; - } - - /* Subtitle */ - if( this->menu_handle < 0 ) { - this->menu_handle = ovl_manager->get_handle(ovl_manager,1); - } - - if( this->menu_handle < 0 ) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec: No video_overlay handles left for menu\n"); - return; - } - this->event.object.handle = this->menu_handle; - this->event.object.pts = this->spudec_stream_state[stream_id].pts; - - xine_fast_memcpy(this->event.object.overlay, - &this->overlay, - sizeof(vo_overlay_t)); - this->overlay.rle=NULL; - /* For force display menus */ - //if ( !(this->state.visible) ) { - // this->state.visible = OVERLAY_EVENT_SHOW; - //} - - this->event.event_type = this->state.visible; - /* - printf("spu event %d handle: %d vpts: %lli\n", this->event.event_type, - this->event.object.handle, this->event.vpts ); - */ - - this->event.vpts = this->spudec_stream_state[stream_id].vpts+(this->state.delay*1000); - - /* Keep all the events in the correct order. */ - /* This corrects for errors during estimation around discontinuity */ - if( this->event.vpts < this->last_event_vpts ) { - this->event.vpts = this->last_event_vpts + 1; - } - this->last_event_vpts = this->event.vpts; - -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", - this->event.event_type, - this->stream->xine->clock->get_current_time(this->stream->xine->clock), - this->event.vpts); -#endif - ovl_manager->add_event(ovl_manager, (void *)&this->event); - } else { - pending = 0; - } - } while (pending); - -} - -#define CMD_SPU_FORCE_DISPLAY 0x00 -#define CMD_SPU_SHOW 0x01 -#define CMD_SPU_HIDE 0x02 -#define CMD_SPU_SET_PALETTE 0x03 -#define CMD_SPU_SET_ALPHA 0x04 -#define CMD_SPU_SET_SIZE 0x05 -#define CMD_SPU_SET_PXD_OFFSET 0x06 -#define CMD_SPU_WIPE 0x07 /* Not currently implemented */ -#define CMD_SPU_EOF 0xff - -static void spudec_do_commands(xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) -{ - uint8_t *buf = state->cmd_ptr; - uint8_t *next_seq; - int32_t param_length; - -#ifdef LOG_DEBUG - printf ("spu: SPU DO COMMANDS\n"); -#endif - - state->delay = (buf[0] << 8) + buf[1]; -#ifdef LOG_DEBUG - printf ("spu: \tdelay=%d\n",state->delay); -#endif - next_seq = seq->buf + (buf[2] << 8) + buf[3]; - buf += 4; -#ifdef LOG_DEBUG - printf ("spu: \tnext_seq=%d\n",next_seq - seq->buf); -#endif - -/* if next equals current, this is the last one - */ - if (state->cmd_ptr >= next_seq) - next_seq = seq->buf + seq->seq_len; /* allow to run until end */ - - state->cmd_ptr = next_seq; - - while (buf < next_seq && *buf != CMD_SPU_EOF) { - switch (*buf) { - case CMD_SPU_SHOW: /* show subpicture */ -#ifdef LOG_DEBUG - printf ("spu: \tshow subpicture\n"); -#endif - state->visible = OVERLAY_EVENT_SHOW; - buf++; - break; - - case CMD_SPU_HIDE: /* hide subpicture */ -#ifdef LOG_DEBUG - printf ("spu: \thide subpicture\n"); -#endif - state->visible = OVERLAY_EVENT_HIDE; - buf++; - break; - - case CMD_SPU_SET_PALETTE: { /* CLUT */ - spudec_clut_t *clut = (spudec_clut_t *) (buf+1); - - state->cur_colors[3] = clut->entry0; - state->cur_colors[2] = clut->entry1; - state->cur_colors[1] = clut->entry2; - state->cur_colors[0] = clut->entry3; - -/* This is a bit out of context for now */ - ovl->color[3] = state->clut[clut->entry0]; - ovl->color[2] = state->clut[clut->entry1]; - ovl->color[1] = state->clut[clut->entry2]; - ovl->color[0] = state->clut[clut->entry3]; - -#ifdef LOG_DEBUG - printf ("spu: \tclut [%x %x %x %x]\n", - ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); - printf ("spu: \tclut base [%x %x %x %x]\n", - clut->entry0, clut->entry1, clut->entry2, clut->entry3); -#endif - state->modified = 1; - buf += 3; - break; - } - case CMD_SPU_SET_ALPHA: { /* transparency palette */ - spudec_clut_t *trans = (spudec_clut_t *) (buf+1); -/* This should go into state for now */ - - ovl->trans[3] = trans->entry0; - ovl->trans[2] = trans->entry1; - ovl->trans[1] = trans->entry2; - ovl->trans[0] = trans->entry3; - -#ifdef LOG_DEBUG - printf ("spu: \ttrans [%d %d %d %d]\n", - ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); -#endif - state->modified = 1; - buf += 3; - break; - } - - case CMD_SPU_SET_SIZE: /* image coordinates */ -/* state->o_left = (buf[1] << 4) | (buf[2] >> 4); - state->o_right = (((buf[2] & 0x0f) << 8) | buf[3]); - - state->o_top = (buf[4] << 4) | (buf[5] >> 4); - state->o_bottom = (((buf[5] & 0x0f) << 8) | buf[6]); - */ - ovl->x = (buf[1] << 4) | (buf[2] >> 4); - ovl->y = (buf[4] << 4) | (buf[5] >> 4); - ovl->width = (((buf[2] & 0x0f) << 8) | buf[3]) - ovl->x + 1; - ovl->height = (((buf[5] & 0x0f) << 8) | buf[6]) - ovl->y + 1; - ovl->hili_top = -1; - ovl->hili_bottom = -1; - ovl->hili_left = -1; - ovl->hili_right = -1; - -#ifdef LOG_DEBUG - printf ("spu: \tx = %d y = %d width = %d height = %d\n", - ovl->x, ovl->y, ovl->width, ovl->height ); -#endif - state->modified = 1; - buf += 7; - break; - - case CMD_SPU_SET_PXD_OFFSET: /* image top[0] field / image bottom[1] field*/ - state->field_offs[0] = (((u_int)buf[1]) << 8) | buf[2]; - state->field_offs[1] = (((u_int)buf[3]) << 8) | buf[4]; - -#ifdef LOG_DEBUG - printf ("spu: \toffset[0] = %d offset[1] = %d\n", - state->field_offs[0], state->field_offs[1]); -#endif - - if ((state->field_offs[0] >= seq->seq_len) || - (state->field_offs[1] >= seq->seq_len)) { - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); - seq->broken = 1; - } - state->modified = 1; - buf += 5; - break; - - case CMD_SPU_WIPE: -#ifdef LOG_DEBUG - printf ("libspudec: \tSPU_WIPE not implemented yet\n"); -#endif - param_length = (buf[1] << 8) | (buf[2]); - buf += 1 + param_length; - break; - - case CMD_SPU_FORCE_DISPLAY: -#ifdef LOG_DEBUG - printf ("libspudec: \tForce Display/Menu\n"); -#endif - state->forced_display = 1; - buf++; - break; - - default: - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec: unknown seqence command (%02x)\n", buf[0]); - /* FIXME: SPU should be dropped, and buffers resynced */ - buf = next_seq; - seq->broken = 1; - break; - } - } - - if (next_seq >= seq->buf + seq->seq_len) - seq->finished = 1; /* last sub-sequence */ -} - -/* FIXME: Get rid of all these static values */ -static uint8_t *bit_ptr[2]; -static int field; // which field we are currently decoding -static int put_x, put_y; - -static u_int get_bits (u_int bits) -{ - static u_int data; - static u_int bits_left; - u_int ret = 0; - - if (!bits) { /* for realignment to next byte */ - bits_left = 0; - } - - while (bits) { - if (bits > bits_left) { - ret |= data << (bits - bits_left); - bits -= bits_left; - - data = *bit_ptr[field]++; - bits_left = 8; - } else { - bits_left -= bits; - ret |= data >> (bits_left); - data &= (1 << bits_left) - 1; - bits = 0; - } - } - - return ret; -} - -static int spudec_next_line (vo_overlay_t *spu) -{ - get_bits (0); // byte align rle data - - put_x = 0; - put_y++; - field ^= 1; // Toggle fields - - if (put_y >= spu->height) { -#ifdef LOG_DEBUG - printf ("spu: put_y >= spu->height\n"); -#endif - return -1; - } - return 0; -} - -static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) -{ - rle_elem_t *rle; - field = 0; - bit_ptr[0] = seq->buf + state->field_offs[0]; - bit_ptr[1] = seq->buf + state->field_offs[1]; - put_x = put_y = 0; - get_bits (0); /* Reset/init bit code */ - -/* ovl->x = state->o_left; - * ovl->y = state->o_top; - * ovl->width = state->o_right - state->o_left + 1; - * ovl->height = state->o_bottom - state->o_top + 1; - - * ovl->hili_top = 0; - * ovl->hili_bottom = ovl->height - 1; - * ovl->hili_left = 0; - * ovl->hili_right = ovl->width - 1; - */ - - /* allocate for the worst case: - * - both fields running to the very end - * - 2 RLE elements per byte meaning single pixel RLE - */ - ovl->data_size = ((seq->cmd_offs - state->field_offs[0]) + - (seq->cmd_offs - state->field_offs[1])) * 2 * sizeof(rle_elem_t); - - if (ovl->rle) { - xprintf (xine, XINE_VERBOSITY_DEBUG, - "libspudec: spudec_draw_picture: ovl->rle is not empty!!!! It should be!!! " - "You should never see this message.\n"); - free(ovl->rle); - ovl->rle=NULL; - } - ovl->rle = malloc(ovl->data_size); - - state->modified = 0; /* mark as already processed */ - rle = ovl->rle; -#ifdef LOG_DEBUG - printf ("libspudec: Draw RLE=%p\n",rle); -#endif - - while (bit_ptr[1] < seq->buf + seq->cmd_offs) { - u_int len; - u_int vlc; - - vlc = get_bits (4); - if (vlc < 0x0004) { - vlc = (vlc << 4) | get_bits (4); - if (vlc < 0x0010) { - vlc = (vlc << 4) | get_bits (4); - if (vlc < 0x0040) { - vlc = (vlc << 4) | get_bits (4); - } - } - } - - len = vlc >> 2; - - /* if len == 0 -> end sequence - fill to end of line */ - if (len == 0) - len = ovl->width - put_x; - - rle->len = len; - rle->color = vlc & 0x03; - rle++; - put_x += len; - - if (put_x >= ovl->width) { - if (spudec_next_line (ovl) < 0) - break; - } - } - - ovl->num_rle = rle - ovl->rle; - ovl->rgb_clut = 0; - ovl->unscaled = 0; -#ifdef LOG_DEBUG - printf ("spu: Num RLE=%d\n",ovl->num_rle); - printf ("spu: Date size=%d\n",ovl->data_size); - printf ("spu: sizeof RLE=%d\n",sizeof(rle_elem_t)); -#endif -} - -/* Heuristic to discover the colors used by the subtitles - and assign a "readable" pallete to them. - Currently looks for sequence of border-fg-border or - border1-border2-fg-border2-border1. - MINFOUND is the number of ocurrences threshold. -*/ -#define MINFOUND 20 -static void spudec_discover_clut(xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl) -{ - int bg,c; - int seqcolor[10]; - int n,i; - rle_elem_t *rle; - - int found[2][16]; - - static clut_t text_clut[] = { - CLUT_Y_CR_CB_INIT(0x80, 0x90, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x90, 0x00), - CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00) - }; - - memset(found,0,sizeof(found)); - rle = ovl->rle; - - /* this seems to be a problem somewhere else, - why rle is null? */ - if( !rle ) - return; - - /* suppose the first and last pixels are bg */ - if( rle[0].color != rle[ovl->num_rle-1].color ) - return; - - bg = rle[0].color; - - i = 0; - for( n = 0; n < ovl->num_rle; n++ ) - { - c = rle[n].color; - - if( c == bg ) - { - if( i == 3 && seqcolor[1] == seqcolor[3] ) - { - found[0][seqcolor[2]]++; - if( found[0][seqcolor[2]] > MINFOUND ) - { - memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[1], - sizeof(clut_t)); - memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[2], - sizeof(clut_t)); - ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; - ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; - state->need_clut = 0; - break; - } - } - if( i == 5 && seqcolor[1] == seqcolor[5] - && seqcolor[2] == seqcolor[4] ) - { - found[1][seqcolor[3]]++; - if( found[1][seqcolor[3]] > MINFOUND ) - { - memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[0], - sizeof(clut_t)); - memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[1], - sizeof(clut_t)); - memcpy(&state->clut[state->cur_colors[seqcolor[3]]], &text_clut[2], - sizeof(clut_t)); - ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; - ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; - ovl->color[seqcolor[3]] = state->clut[state->cur_colors[seqcolor[3]]]; - state->need_clut = 0; - break; - } - } - i = 0; - seqcolor[i] = c; - } - else if ( i < 6 ) - { - i++; - seqcolor[i] = c; - } - } -} - -#ifdef LOG_DEBUG -static void spudec_print_overlay( vo_overlay_t *ovl ) { - printf ("spu: OVERLAY to show\n"); - printf ("spu: \tx = %d y = %d width = %d height = %d\n", - ovl->x, ovl->y, ovl->width, ovl->height ); - printf ("spu: \tclut [%x %x %x %x]\n", - ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); - printf ("spu: \ttrans [%d %d %d %d]\n", - ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); - printf ("spu: \tclip top=%d bottom=%d left=%d right=%d\n", - ovl->hili_top, ovl->hili_bottom, ovl->hili_left, ovl->hili_right); - printf ("spu: \tclip_clut [%x %x %x %x]\n", - ovl->hili_color[0], ovl->hili_color[1], ovl->hili_color[2], ovl->hili_color[3]); - printf ("spu: \thili_trans [%d %d %d %d]\n", - ovl->hili_trans[0], ovl->hili_trans[1], ovl->hili_trans[2], ovl->hili_trans[3]); - return; -} -#endif - -int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, - int32_t button, int32_t mode, vo_overlay_t * overlay, vo_overlay_t * base ) { - btni_t *button_ptr = NULL; - unsigned int btns_per_group; - int i; - - if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) - return 0; - - btns_per_group = 36 / nav_pci->hli.hl_gi.btngr_ns; - - /* choose button group: we can always use a normal 4:3 or widescreen button group - * as long as xine blends the overlay before scaling the image to its aspect */ - if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 1 && !(nav_pci->hli.hl_gi.btngr1_dsp_ty & 6)) - button_ptr = &nav_pci->hli.btnit[0 * btns_per_group + button - 1]; - if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 2 && !(nav_pci->hli.hl_gi.btngr2_dsp_ty & 6)) - button_ptr = &nav_pci->hli.btnit[1 * btns_per_group + button - 1]; - if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 3 && !(nav_pci->hli.hl_gi.btngr3_dsp_ty & 6)) - button_ptr = &nav_pci->hli.btnit[2 * btns_per_group + button - 1]; - if (!button_ptr) { - xprintf(xine, XINE_VERBOSITY_DEBUG, - "libspudec: No suitable menu button group found, using group 1.\n"); - button_ptr = &nav_pci->hli.btnit[button - 1]; - } - - /* button areas in the nav packet are in screen coordinates, - * overlay clipping areas are in overlay coordinates; - * therefore we must subtract the display coordinates of the underlying overlay */ - overlay->hili_left = (button_ptr->x_start > base->x) ? (button_ptr->x_start - base->x) : 0; - overlay->hili_top = (button_ptr->y_start > base->y) ? (button_ptr->y_start - base->y) : 0; - overlay->hili_right = (button_ptr->x_end > base->x) ? (button_ptr->x_end - base->x) : 0; - overlay->hili_bottom = (button_ptr->y_end > base->y) ? (button_ptr->y_end - base->y) : 0; - if(button_ptr->btn_coln != 0) { -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: normal button clut\n"); -#endif - for (i = 0;i < 4; i++) { - overlay->hili_color[i] = clut[0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (16 + 4*i))]; - overlay->hili_trans[i] = 0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (4*i)); - } - } else { -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: abnormal button clut\n"); -#endif - for (i = 0;i < 4; i++) { -#ifdef LOG_BUTTON - printf("libspudec:btn_coln = 0, hili_color = color\n"); -#endif - overlay->hili_color[i] = overlay->color[i]; - overlay->hili_trans[i] = overlay->trans[i]; - } - } - - /* spudec_print_overlay( overlay ); */ -#ifdef LOG_BUTTON - printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n"); -#endif - - return 1; -} diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h deleted file mode 100644 index 1e7d80596..000000000 --- a/src/libspudec/spu.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * This file was originally part of the OMS program. - */ - -#ifndef __SPU_H__ -#define __SPU_H__ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#ifdef HAVE_DVDNAV -# include -#else -# include "nav_types.h" -#endif - -#define NUM_SEQ_BUFFERS 50 -#define MAX_STREAMS 32 - -typedef struct spudec_clut_struct { -#ifdef WORDS_BIGENDIAN - uint8_t entry0 : 4; - uint8_t entry1 : 4; - uint8_t entry2 : 4; - uint8_t entry3 : 4; -#else - uint8_t entry1 : 4; - uint8_t entry0 : 4; - uint8_t entry3 : 4; - uint8_t entry2 : 4; -#endif -} spudec_clut_t; - -typedef struct { - uint8_t *buf; - uint32_t ra_offs; /* reassembly offset */ - uint32_t seq_len; - uint32_t buf_len; - uint32_t cmd_offs; - int64_t pts; /* Base PTS of this sequence */ - int32_t finished; /* Has this control sequence been finished? */ - uint32_t complete; /* Has this reassembly been finished? */ - uint32_t broken; /* this SPU is broken and should be dropped */ -} spudec_seq_t; - -typedef struct { - uint8_t *cmd_ptr; - - uint32_t field_offs[2]; - int32_t b_top, o_top; - int32_t b_bottom, o_bottom; - int32_t b_left, o_left; - int32_t b_right, o_right; - - int32_t modified; /* Was the sub-picture modified? */ - int32_t visible; /* Must the sub-picture be shown? */ - int32_t forced_display; /* This overlay is a menu */ - int32_t delay; /* Delay in 90Khz / 1000 */ - int32_t need_clut; /* doesn't have the right clut yet */ - int32_t cur_colors[4];/* current 4 colors been used */ - int32_t vobsub; /* vobsub must be aligned to bottom */ - - uint32_t clut[16]; -} spudec_state_t; - -typedef struct spudec_stream_state_s { - spudec_seq_t ra_seq; - spudec_state_t state; - int64_t vpts; - int64_t pts; - int32_t overlay_handle; -} spudec_stream_state_t; - -typedef struct { - spu_decoder_class_t decoder_class; -} spudec_class_t; - -typedef struct pci_node_s pci_node_t; -struct pci_node_s { - pci_t pci; - uint64_t vpts; - pci_node_t *next; -}; - -typedef struct spudec_decoder_s { - spu_decoder_t spu_decoder; - - spudec_class_t *class; - xine_stream_t *stream; - spudec_stream_state_t spudec_stream_state[MAX_STREAMS]; - - video_overlay_event_t event; - video_overlay_object_t object; - int32_t menu_handle; - - spudec_state_t state; - - vo_overlay_t overlay; - int ovl_caps; - int output_open; - pthread_mutex_t nav_pci_lock; - pci_node_t pci_cur; - uint32_t buttonN; /* Current button number for highlights */ - int32_t button_filter; /* Allow highlight changes or not */ - int64_t last_event_vpts; -} spudec_decoder_t; - -void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len); -void spudec_process( spudec_decoder_t *this, int stream_id); -/* the nav functions must be called with the nav_pci_lock held */ -void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf); -void spudec_clear_nav_list(spudec_decoder_t *this); -void spudec_update_nav(spudec_decoder_t *this); -void spudec_process_nav(spudec_decoder_t *this); -int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, int32_t button, int32_t mode, - vo_overlay_t * overlay, vo_overlay_t * base ); - -#endif diff --git a/src/libspudec/spudec.c b/src/libspudec/spudec.c new file mode 100644 index 000000000..13136a53f --- /dev/null +++ b/src/libspudec/spudec.c @@ -0,0 +1,1026 @@ +/* + * Copyright (C) 2002-2004 the xine project + * + * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 + * + * spu.c - converts DVD subtitles to an XPM image + * + * Mostly based on hard work by: + * + * Copyright (C) 2000 Samuel Hocevar + * and Michel Lespinasse + * + * Lots of rearranging by: + * Aaron Holtzman + * Thomas Mirlacher + * implemented reassembling + * cleaner implementation of SPU are saving + * overlaying (proof of concept for now) + * ... and yes, it works now with oms + * added tranparency (provided by the SPU hdr) + * changed structures for easy porting to MGAs DVD mode + * This file is part of xine + * This file was originally part of the OMS program. + * + * This program 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, or (at your option) + * any later version. + * + * This program 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "xine-engine/bswap.h" +#ifdef HAVE_DVDNAV +# include +# include +#else +# include "nav_read.h" +# include "nav_print.h" +#endif + +#include "spudec.h" + +/* +#define LOG_DEBUG 1 +#define LOG_BUTTON 1 +#define LOG_NAV 1 +*/ + +static void spudec_do_commands (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); +static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); +static void spudec_discover_clut (xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl); +#ifdef LOG_DEBUG +static void spudec_print_overlay( vo_overlay_t *overlay ); +#endif + +void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) { + uint8_t *p; + uint32_t packet_len; + uint32_t stream_id; + uint32_t header_len; + pci_t pci; + dsi_t dsi; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + + p = buf->content; + if (p[0] || p[1] || (p[2] != 1)) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec:spudec_decode_nav:nav demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); + return; + } + + packet_len = p[4] << 8 | p[5]; + stream_id = p[3]; + + header_len = 6; + p += header_len; + + if (stream_id == 0xbf) { /* Private stream 2 */ +/* int i; + * for(i=0;i<80;i++) { + * printf("%02x ",p[i]); + * } + * printf("\n p[0]=0x%02x\n",p[0]); + */ + if(p[0] == 0x00) { +#ifdef LOG_NAV + printf("libspudec:nav_PCI\n"); +#endif + navRead_PCI(&pci, p+1); +#ifdef LOG_NAV + printf("libspudec:nav:hli_ss=%u, hli_s_ptm=%u, hli_e_ptm=%u, btn_sl_e_ptm=%u pts=%lli\n", + pci.hli.hl_gi.hli_ss, + pci.hli.hl_gi.hli_s_ptm, + pci.hli.hl_gi.hli_e_ptm, + pci.hli.hl_gi.btn_se_e_ptm, + buf->pts); + printf("libspudec:nav:btn_sn/ofn=%u, btn_ns=%u, fosl_btnn=%u, foac_btnn=%u\n", + pci.hli.hl_gi.btn_ofn, pci.hli.hl_gi.btn_ns, + pci.hli.hl_gi.fosl_btnn, pci.hli.hl_gi.foac_btnn); + printf("btngr_ns %d\n", pci.hli.hl_gi.btngr_ns); + printf("btngr%d_dsp_ty 0x%02x\n", 1, pci.hli.hl_gi.btngr1_dsp_ty); + printf("btngr%d_dsp_ty 0x%02x\n", 2, pci.hli.hl_gi.btngr2_dsp_ty); + printf("btngr%d_dsp_ty 0x%02x\n", 3, pci.hli.hl_gi.btngr3_dsp_ty); + //navPrint_PCI(&pci); + //navPrint_PCI_GI(&pci.pci_gi); + //navPrint_NSML_AGLI(&pci.nsml_agli); + //navPrint_HLI(&pci.hli); + //navPrint_HL_GI(&pci.hli.hl_gi, & btngr_ns, & btn_ns); +#endif + } + + p += packet_len; + + /* We should now have a DSI packet. */ + /* We don't need anything from the DSI packet here. */ + if(p[6] == 0x01) { + packet_len = p[4] << 8 | p[5]; + p += 6; +#ifdef LOG_NAV + printf("NAV DSI packet\n"); +#endif + navRead_DSI(&dsi, p+1); + +// self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; +// self->vobu_length = self->dsi.dsi_gi.vobu_ea; + } + } + + /* NAV packets contain start and end presentation timestamps, which tell the + * application, when the highlight information in the NAV is supposed to be valid. + * We handle these timestamps only in a very stripped-down way: We keep a list + * of NAV packets (or better: the PCI part of them), tagged with a VPTS timestamp + * telling, when the NAV should be processed. However, we only enqueue a new node + * into this list, when we receive new highlight information during an already + * showing menu. This happens very rarerly on common DVDs, so it is of low impact. + * And we only check for processing of queued entries at some prominent + * locations in this SPU decoder. Since presentation timestamps rarely solve a real + * purpose on most DVDs, this is ok compared to the full-blown solution, which would + * require a separate thread managing the queue all the time. */ + pthread_mutex_lock(&this->nav_pci_lock); + switch (pci.hli.hl_gi.hli_ss) { + case 0: + /* No Highlight information for this VOBU */ + if ( this->pci_cur.pci.hli.hl_gi.hli_ss == 1) { + /* Hide menu spu between menus */ +#ifdef LOG_BUTTON + printf("libspudec:nav:SHOULD HIDE SPU here\n"); +#endif + if( this->menu_handle < 0 ) { + this->menu_handle = ovl_manager->get_handle(ovl_manager,1); + } + if( this->menu_handle >= 0 ) { + this->event.object.handle = this->menu_handle; + this->event.event_type = OVERLAY_EVENT_HIDE; + /* hide menu right now */ + this->event.vpts = 0; + ovl_manager->add_event(ovl_manager, (void *)&this->event); + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: No video_overlay handles left for menu\n"); + } + } + spudec_clear_nav_list(this); + xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); + /* incoming SPUs will be plain subtitles */ + this->event.object.object_type = 0; + if (this->button_filter) { + /* we possibly had buttons before, so we update the UI info */ + xine_event_t event; + xine_ui_data_t data; + + event.type = XINE_EVENT_UI_NUM_BUTTONS; + event.data = &data; + event.data_length = sizeof(data); + data.num_buttons = 0; + + xine_event_send(this->stream, &event); + } + this->button_filter=0; + + break; + case 1: + /* All New Highlight information for this VOBU */ + if (this->pci_cur.pci.hli.hl_gi.hli_ss != 0 && + pci.hli.hl_gi.hli_s_ptm > this->pci_cur.pci.hli.hl_gi.hli_s_ptm) { + pci_node_t *node = &this->pci_cur; +#ifdef LOG_DEBUG + printf("libspudec: allocating new PCI node for hli_s_ptm %d\n", pci.hli.hl_gi.hli_s_ptm); +#endif + /* append PCI at the end of the list */ + while (node->next) node = node->next; + node->next = (pci_node_t *)xine_xmalloc(sizeof(pci_node_t)); + node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm); + node->next->next = NULL; + xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t)); + } else { + spudec_clear_nav_list(this); + /* menu ahead, remember PCI for later use */ + xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); + spudec_process_nav(this); + } + break; + case 2: + /* Use Highlight information from previous VOBU */ + if (this->pci_cur.next) { + /* apply changes to last enqueued NAV */ + pci_node_t *node = this->pci_cur.next; + while (node->next) node = node->next; + node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + spudec_update_nav(this); + } else { + this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + } + break; + case 3: + /* Use Highlight information from previous VOBU except commands, which come from this VOBU */ + if (this->pci_cur.next) { + /* apply changes to last enqueued NAV */ + pci_node_t *node = this->pci_cur.next; + while (node->next) node = node->next; + node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + /* FIXME: Add command copying here */ + spudec_update_nav(this); + } else { + this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + /* FIXME: Add command copying here */ + } + break; + default: + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec: unknown pci.hli.hl_gi.hli_ss = %d\n", pci.hli.hl_gi.hli_ss ); + break; + } + pthread_mutex_unlock(&this->nav_pci_lock); + return; +} + +void spudec_clear_nav_list(spudec_decoder_t *this) +{ + while (this->pci_cur.next) { + pci_node_t *node = this->pci_cur.next->next; + free(this->pci_cur.next); + this->pci_cur.next = node; + } + /* invalidate current timestamp */ + this->pci_cur.pci.hli.hl_gi.hli_s_ptm = (uint32_t)-1; +} + +void spudec_update_nav(spudec_decoder_t *this) +{ + metronom_clock_t *clock = this->stream->xine->clock; + + if (this->pci_cur.next && this->pci_cur.next->vpts <= clock->get_current_time(clock)) { + pci_node_t *node = this->pci_cur.next; + xine_fast_memcpy(&this->pci_cur, this->pci_cur.next, sizeof(pci_node_t)); + spudec_process_nav(this); + free(node); + } +} + +void spudec_process_nav(spudec_decoder_t *this) +{ + /* incoming SPUs will be menus */ + this->event.object.object_type = 1; + if (!this->button_filter) { + /* we possibly entered a menu, so we update the UI button info */ + xine_event_t event; + xine_ui_data_t data; + + event.type = XINE_EVENT_UI_NUM_BUTTONS; + event.data = &data; + event.data_length = sizeof(data); + data.num_buttons = this->pci_cur.pci.hli.hl_gi.btn_ns; + + xine_event_send(this->stream, &event); + } + this->button_filter=1; +} + +void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len) +{ +#ifdef LOG_DEBUG + printf ("libspudec: seq->complete = %d\n", seq->complete); + printf("libspudec:1: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", + seq->ra_offs, + seq->seq_len, + seq->buf_len, + seq->buf); +#endif + if (seq->complete) { + seq->seq_len = (((uint32_t)pkt_data[0])<<8) | pkt_data[1]; + seq->cmd_offs = (((uint32_t)pkt_data[2])<<8) | pkt_data[3]; + if (seq->cmd_offs >= seq->seq_len) { + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); + seq->broken = 1; + } + if (seq->buf_len < seq->seq_len) { + seq->buf_len = seq->seq_len; +#ifdef LOG_DEBUG + printf ("spu: MALLOC1: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); +#endif + if (seq->buf) { + free(seq->buf); + seq->buf = NULL; + } + seq->buf = malloc(seq->buf_len); +#ifdef LOG_DEBUG + printf ("spu: MALLOC2: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); +#endif + + } + seq->ra_offs = 0; + +#ifdef LOG_DEBUG + printf ("spu: buf_len: %d\n", seq->buf_len); + printf ("spu: cmd_off: %d\n", seq->cmd_offs); +#endif + } + +#ifdef LOG_DEBUG + printf("libspudec:2: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", + seq->ra_offs, + seq->seq_len, + seq->buf_len, + seq->buf); +#endif + if (seq->ra_offs < seq->seq_len) { + if (seq->ra_offs + pkt_len > seq->seq_len) + pkt_len = seq->seq_len - seq->ra_offs; + memcpy (seq->buf + seq->ra_offs, pkt_data, pkt_len); + seq->ra_offs += pkt_len; + } else { + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); + seq->broken = 1; + } + + if (seq->ra_offs == seq->seq_len) { + seq->finished = 0; + seq->complete = 1; + return; /* sequence ready */ + } + seq->complete = 0; + return; +} + +void spudec_process (spudec_decoder_t *this, int stream_id) { + spudec_seq_t *cur_seq; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + int pending = 1; + cur_seq = &this->spudec_stream_state[stream_id].ra_seq; + +#ifdef LOG_DEBUG + printf ("spu: Found SPU from stream %d pts=%lli vpts=%lli\n",stream_id, + this->spudec_stream_state[stream_id].pts, + this->spudec_stream_state[stream_id].vpts); +#endif + this->state.cmd_ptr = cur_seq->buf + cur_seq->cmd_offs; + this->state.modified = 1; /* Only draw picture if = 1 on first event of SPU */ + this->state.visible = OVERLAY_EVENT_SHOW; + this->state.forced_display = 0; /* 0 - No value, 1 - Forced Display. */ + this->state.delay = 0; + cur_seq->finished=0; + + do { + if (!(cur_seq->finished) ) { + pci_node_t *node; + + /* spu_channel is now set based on whether we are in the menu or not. */ + /* Bit 7 is set if only forced display SPUs should be shown */ + if ( (this->stream->spu_channel & 0x1f) != stream_id ) { +#ifdef LOG_DEBUG + printf ("spu: Dropping SPU channel %d. Not selected stream_id\n", stream_id); +#endif + return; + } + /* parse SPU command sequence, this will update forced_display, so it must come + * before the check for it */ + spudec_do_commands(this->stream->xine, &this->state, cur_seq, &this->overlay); + /* FIXME: Check for Forced-display or subtitle stream + * For subtitles, open event. + * For menus, store it for later. + */ + if (cur_seq->broken) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); + cur_seq->broken = 0; + return; + } + if ( (this->state.forced_display == 0) && (this->stream->spu_channel & 0x80) ) { +#ifdef LOG_DEBUG + printf ("spu: Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id); +#endif + return; + } + +#ifdef LOG_DEBUG + spudec_print_overlay( &this->overlay ); + printf ("spu: forced display:%s\n", this->state.forced_display ? "Yes" : "No" ); +#endif + pthread_mutex_lock(&this->nav_pci_lock); + /* search for a PCI that matches this SPU's PTS */ + for (node = &this->pci_cur; node; node = node->next) + if (node->pci.hli.hl_gi.hli_s_ptm == this->spudec_stream_state[stream_id].pts) + break; + if (node) { + if (this->state.visible == OVERLAY_EVENT_HIDE) { + /* menus are hidden via nav packet decoding, not here */ + /* FIXME: James is not sure about this solution and may want to look this over. + * I'm commiting it, because I haven't found a disc it breaks, but it fixes + * some instead. Michael Roitzsch */ + pthread_mutex_unlock(&this->nav_pci_lock); + continue; + } + if (node->pci.hli.hl_gi.fosl_btnn > 0) { + xine_event_t event; + + this->buttonN = node->pci.hli.hl_gi.fosl_btnn; + event.type = XINE_EVENT_INPUT_BUTTON_FORCE; + event.stream = this->stream; + event.data = &this->buttonN; + event.data_length = sizeof(this->buttonN); + xine_event_send(this->stream, &event); + } +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec:Full Overlay\n"); +#endif + if (!spudec_copy_nav_to_overlay(this->stream->xine, + &node->pci, this->state.clut, + this->buttonN, 0, &this->overlay, &this->overlay)) { + /* current button does not exist -> use another one */ + xine_event_t event; + + if (this->buttonN > node->pci.hli.hl_gi.btn_ns) + this->buttonN = node->pci.hli.hl_gi.btn_ns; + else + this->buttonN = 1; + event.type = XINE_EVENT_INPUT_BUTTON_FORCE; + event.stream = this->stream; + event.data = &this->buttonN; + event.data_length = sizeof(this->buttonN); + xine_event_send(this->stream, &event); + spudec_copy_nav_to_overlay(this->stream->xine, + &node->pci, this->state.clut, + this->buttonN, 0, &this->overlay, &this->overlay); + } + } else { + /* Subtitle and not a menu button */ + int i; + for (i = 0;i < 4; i++) { + this->overlay.hili_color[i] = this->overlay.color[i]; + this->overlay.hili_trans[i] = this->overlay.trans[i]; + } + } + pthread_mutex_unlock(&this->nav_pci_lock); + + if ((this->state.modified) ) { + spudec_draw_picture(this->stream->xine, &this->state, cur_seq, &this->overlay); + } + + if (this->state.need_clut) { + spudec_discover_clut(this->stream->xine, &this->state, &this->overlay); + } + + if (this->state.vobsub) { + int width, height; + int64_t duration; + + /* + * vobsubs are usually played with a scaled-down stream (not full DVD + * resolution), therefore we should try to realign it. + */ + + this->stream->video_out->status(this->stream->video_out, NULL, + &width, &height, &duration ); + + this->overlay.x = (width - this->overlay.width) / 2; + this->overlay.y = height - this->overlay.height; + } + + /* Subtitle */ + if( this->menu_handle < 0 ) { + this->menu_handle = ovl_manager->get_handle(ovl_manager,1); + } + + if( this->menu_handle < 0 ) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec: No video_overlay handles left for menu\n"); + return; + } + this->event.object.handle = this->menu_handle; + this->event.object.pts = this->spudec_stream_state[stream_id].pts; + + xine_fast_memcpy(this->event.object.overlay, + &this->overlay, + sizeof(vo_overlay_t)); + this->overlay.rle=NULL; + /* For force display menus */ + //if ( !(this->state.visible) ) { + // this->state.visible = OVERLAY_EVENT_SHOW; + //} + + this->event.event_type = this->state.visible; + /* + printf("spu event %d handle: %d vpts: %lli\n", this->event.event_type, + this->event.object.handle, this->event.vpts ); + */ + + this->event.vpts = this->spudec_stream_state[stream_id].vpts+(this->state.delay*1000); + + /* Keep all the events in the correct order. */ + /* This corrects for errors during estimation around discontinuity */ + if( this->event.vpts < this->last_event_vpts ) { + this->event.vpts = this->last_event_vpts + 1; + } + this->last_event_vpts = this->event.vpts; + +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", + this->event.event_type, + this->stream->xine->clock->get_current_time(this->stream->xine->clock), + this->event.vpts); +#endif + ovl_manager->add_event(ovl_manager, (void *)&this->event); + } else { + pending = 0; + } + } while (pending); + +} + +#define CMD_SPU_FORCE_DISPLAY 0x00 +#define CMD_SPU_SHOW 0x01 +#define CMD_SPU_HIDE 0x02 +#define CMD_SPU_SET_PALETTE 0x03 +#define CMD_SPU_SET_ALPHA 0x04 +#define CMD_SPU_SET_SIZE 0x05 +#define CMD_SPU_SET_PXD_OFFSET 0x06 +#define CMD_SPU_WIPE 0x07 /* Not currently implemented */ +#define CMD_SPU_EOF 0xff + +static void spudec_do_commands(xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) +{ + uint8_t *buf = state->cmd_ptr; + uint8_t *next_seq; + int32_t param_length; + +#ifdef LOG_DEBUG + printf ("spu: SPU DO COMMANDS\n"); +#endif + + state->delay = (buf[0] << 8) + buf[1]; +#ifdef LOG_DEBUG + printf ("spu: \tdelay=%d\n",state->delay); +#endif + next_seq = seq->buf + (buf[2] << 8) + buf[3]; + buf += 4; +#ifdef LOG_DEBUG + printf ("spu: \tnext_seq=%d\n",next_seq - seq->buf); +#endif + +/* if next equals current, this is the last one + */ + if (state->cmd_ptr >= next_seq) + next_seq = seq->buf + seq->seq_len; /* allow to run until end */ + + state->cmd_ptr = next_seq; + + while (buf < next_seq && *buf != CMD_SPU_EOF) { + switch (*buf) { + case CMD_SPU_SHOW: /* show subpicture */ +#ifdef LOG_DEBUG + printf ("spu: \tshow subpicture\n"); +#endif + state->visible = OVERLAY_EVENT_SHOW; + buf++; + break; + + case CMD_SPU_HIDE: /* hide subpicture */ +#ifdef LOG_DEBUG + printf ("spu: \thide subpicture\n"); +#endif + state->visible = OVERLAY_EVENT_HIDE; + buf++; + break; + + case CMD_SPU_SET_PALETTE: { /* CLUT */ + spudec_clut_t *clut = (spudec_clut_t *) (buf+1); + + state->cur_colors[3] = clut->entry0; + state->cur_colors[2] = clut->entry1; + state->cur_colors[1] = clut->entry2; + state->cur_colors[0] = clut->entry3; + +/* This is a bit out of context for now */ + ovl->color[3] = state->clut[clut->entry0]; + ovl->color[2] = state->clut[clut->entry1]; + ovl->color[1] = state->clut[clut->entry2]; + ovl->color[0] = state->clut[clut->entry3]; + +#ifdef LOG_DEBUG + printf ("spu: \tclut [%x %x %x %x]\n", + ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); + printf ("spu: \tclut base [%x %x %x %x]\n", + clut->entry0, clut->entry1, clut->entry2, clut->entry3); +#endif + state->modified = 1; + buf += 3; + break; + } + case CMD_SPU_SET_ALPHA: { /* transparency palette */ + spudec_clut_t *trans = (spudec_clut_t *) (buf+1); +/* This should go into state for now */ + + ovl->trans[3] = trans->entry0; + ovl->trans[2] = trans->entry1; + ovl->trans[1] = trans->entry2; + ovl->trans[0] = trans->entry3; + +#ifdef LOG_DEBUG + printf ("spu: \ttrans [%d %d %d %d]\n", + ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); +#endif + state->modified = 1; + buf += 3; + break; + } + + case CMD_SPU_SET_SIZE: /* image coordinates */ +/* state->o_left = (buf[1] << 4) | (buf[2] >> 4); + state->o_right = (((buf[2] & 0x0f) << 8) | buf[3]); + + state->o_top = (buf[4] << 4) | (buf[5] >> 4); + state->o_bottom = (((buf[5] & 0x0f) << 8) | buf[6]); + */ + ovl->x = (buf[1] << 4) | (buf[2] >> 4); + ovl->y = (buf[4] << 4) | (buf[5] >> 4); + ovl->width = (((buf[2] & 0x0f) << 8) | buf[3]) - ovl->x + 1; + ovl->height = (((buf[5] & 0x0f) << 8) | buf[6]) - ovl->y + 1; + ovl->hili_top = -1; + ovl->hili_bottom = -1; + ovl->hili_left = -1; + ovl->hili_right = -1; + +#ifdef LOG_DEBUG + printf ("spu: \tx = %d y = %d width = %d height = %d\n", + ovl->x, ovl->y, ovl->width, ovl->height ); +#endif + state->modified = 1; + buf += 7; + break; + + case CMD_SPU_SET_PXD_OFFSET: /* image top[0] field / image bottom[1] field*/ + state->field_offs[0] = (((u_int)buf[1]) << 8) | buf[2]; + state->field_offs[1] = (((u_int)buf[3]) << 8) | buf[4]; + +#ifdef LOG_DEBUG + printf ("spu: \toffset[0] = %d offset[1] = %d\n", + state->field_offs[0], state->field_offs[1]); +#endif + + if ((state->field_offs[0] >= seq->seq_len) || + (state->field_offs[1] >= seq->seq_len)) { + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); + seq->broken = 1; + } + state->modified = 1; + buf += 5; + break; + + case CMD_SPU_WIPE: +#ifdef LOG_DEBUG + printf ("libspudec: \tSPU_WIPE not implemented yet\n"); +#endif + param_length = (buf[1] << 8) | (buf[2]); + buf += 1 + param_length; + break; + + case CMD_SPU_FORCE_DISPLAY: +#ifdef LOG_DEBUG + printf ("libspudec: \tForce Display/Menu\n"); +#endif + state->forced_display = 1; + buf++; + break; + + default: + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec: unknown seqence command (%02x)\n", buf[0]); + /* FIXME: SPU should be dropped, and buffers resynced */ + buf = next_seq; + seq->broken = 1; + break; + } + } + + if (next_seq >= seq->buf + seq->seq_len) + seq->finished = 1; /* last sub-sequence */ +} + +/* FIXME: Get rid of all these static values */ +static uint8_t *bit_ptr[2]; +static int field; // which field we are currently decoding +static int put_x, put_y; + +static u_int get_bits (u_int bits) +{ + static u_int data; + static u_int bits_left; + u_int ret = 0; + + if (!bits) { /* for realignment to next byte */ + bits_left = 0; + } + + while (bits) { + if (bits > bits_left) { + ret |= data << (bits - bits_left); + bits -= bits_left; + + data = *bit_ptr[field]++; + bits_left = 8; + } else { + bits_left -= bits; + ret |= data >> (bits_left); + data &= (1 << bits_left) - 1; + bits = 0; + } + } + + return ret; +} + +static int spudec_next_line (vo_overlay_t *spu) +{ + get_bits (0); // byte align rle data + + put_x = 0; + put_y++; + field ^= 1; // Toggle fields + + if (put_y >= spu->height) { +#ifdef LOG_DEBUG + printf ("spu: put_y >= spu->height\n"); +#endif + return -1; + } + return 0; +} + +static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) +{ + rle_elem_t *rle; + field = 0; + bit_ptr[0] = seq->buf + state->field_offs[0]; + bit_ptr[1] = seq->buf + state->field_offs[1]; + put_x = put_y = 0; + get_bits (0); /* Reset/init bit code */ + +/* ovl->x = state->o_left; + * ovl->y = state->o_top; + * ovl->width = state->o_right - state->o_left + 1; + * ovl->height = state->o_bottom - state->o_top + 1; + + * ovl->hili_top = 0; + * ovl->hili_bottom = ovl->height - 1; + * ovl->hili_left = 0; + * ovl->hili_right = ovl->width - 1; + */ + + /* allocate for the worst case: + * - both fields running to the very end + * - 2 RLE elements per byte meaning single pixel RLE + */ + ovl->data_size = ((seq->cmd_offs - state->field_offs[0]) + + (seq->cmd_offs - state->field_offs[1])) * 2 * sizeof(rle_elem_t); + + if (ovl->rle) { + xprintf (xine, XINE_VERBOSITY_DEBUG, + "libspudec: spudec_draw_picture: ovl->rle is not empty!!!! It should be!!! " + "You should never see this message.\n"); + free(ovl->rle); + ovl->rle=NULL; + } + ovl->rle = malloc(ovl->data_size); + + state->modified = 0; /* mark as already processed */ + rle = ovl->rle; +#ifdef LOG_DEBUG + printf ("libspudec: Draw RLE=%p\n",rle); +#endif + + while (bit_ptr[1] < seq->buf + seq->cmd_offs) { + u_int len; + u_int vlc; + + vlc = get_bits (4); + if (vlc < 0x0004) { + vlc = (vlc << 4) | get_bits (4); + if (vlc < 0x0010) { + vlc = (vlc << 4) | get_bits (4); + if (vlc < 0x0040) { + vlc = (vlc << 4) | get_bits (4); + } + } + } + + len = vlc >> 2; + + /* if len == 0 -> end sequence - fill to end of line */ + if (len == 0) + len = ovl->width - put_x; + + rle->len = len; + rle->color = vlc & 0x03; + rle++; + put_x += len; + + if (put_x >= ovl->width) { + if (spudec_next_line (ovl) < 0) + break; + } + } + + ovl->num_rle = rle - ovl->rle; + ovl->rgb_clut = 0; + ovl->unscaled = 0; +#ifdef LOG_DEBUG + printf ("spu: Num RLE=%d\n",ovl->num_rle); + printf ("spu: Date size=%d\n",ovl->data_size); + printf ("spu: sizeof RLE=%d\n",sizeof(rle_elem_t)); +#endif +} + +/* Heuristic to discover the colors used by the subtitles + and assign a "readable" pallete to them. + Currently looks for sequence of border-fg-border or + border1-border2-fg-border2-border1. + MINFOUND is the number of ocurrences threshold. +*/ +#define MINFOUND 20 +static void spudec_discover_clut(xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl) +{ + int bg,c; + int seqcolor[10]; + int n,i; + rle_elem_t *rle; + + int found[2][16]; + + static clut_t text_clut[] = { + CLUT_Y_CR_CB_INIT(0x80, 0x90, 0x80), + CLUT_Y_CR_CB_INIT(0x00, 0x90, 0x00), + CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00) + }; + + memset(found,0,sizeof(found)); + rle = ovl->rle; + + /* this seems to be a problem somewhere else, + why rle is null? */ + if( !rle ) + return; + + /* suppose the first and last pixels are bg */ + if( rle[0].color != rle[ovl->num_rle-1].color ) + return; + + bg = rle[0].color; + + i = 0; + for( n = 0; n < ovl->num_rle; n++ ) + { + c = rle[n].color; + + if( c == bg ) + { + if( i == 3 && seqcolor[1] == seqcolor[3] ) + { + found[0][seqcolor[2]]++; + if( found[0][seqcolor[2]] > MINFOUND ) + { + memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[1], + sizeof(clut_t)); + memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[2], + sizeof(clut_t)); + ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; + ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; + state->need_clut = 0; + break; + } + } + if( i == 5 && seqcolor[1] == seqcolor[5] + && seqcolor[2] == seqcolor[4] ) + { + found[1][seqcolor[3]]++; + if( found[1][seqcolor[3]] > MINFOUND ) + { + memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[0], + sizeof(clut_t)); + memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[1], + sizeof(clut_t)); + memcpy(&state->clut[state->cur_colors[seqcolor[3]]], &text_clut[2], + sizeof(clut_t)); + ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; + ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; + ovl->color[seqcolor[3]] = state->clut[state->cur_colors[seqcolor[3]]]; + state->need_clut = 0; + break; + } + } + i = 0; + seqcolor[i] = c; + } + else if ( i < 6 ) + { + i++; + seqcolor[i] = c; + } + } +} + +#ifdef LOG_DEBUG +static void spudec_print_overlay( vo_overlay_t *ovl ) { + printf ("spu: OVERLAY to show\n"); + printf ("spu: \tx = %d y = %d width = %d height = %d\n", + ovl->x, ovl->y, ovl->width, ovl->height ); + printf ("spu: \tclut [%x %x %x %x]\n", + ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); + printf ("spu: \ttrans [%d %d %d %d]\n", + ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); + printf ("spu: \tclip top=%d bottom=%d left=%d right=%d\n", + ovl->hili_top, ovl->hili_bottom, ovl->hili_left, ovl->hili_right); + printf ("spu: \tclip_clut [%x %x %x %x]\n", + ovl->hili_color[0], ovl->hili_color[1], ovl->hili_color[2], ovl->hili_color[3]); + printf ("spu: \thili_trans [%d %d %d %d]\n", + ovl->hili_trans[0], ovl->hili_trans[1], ovl->hili_trans[2], ovl->hili_trans[3]); + return; +} +#endif + +int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, + int32_t button, int32_t mode, vo_overlay_t * overlay, vo_overlay_t * base ) { + btni_t *button_ptr = NULL; + unsigned int btns_per_group; + int i; + + if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) + return 0; + + btns_per_group = 36 / nav_pci->hli.hl_gi.btngr_ns; + + /* choose button group: we can always use a normal 4:3 or widescreen button group + * as long as xine blends the overlay before scaling the image to its aspect */ + if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 1 && !(nav_pci->hli.hl_gi.btngr1_dsp_ty & 6)) + button_ptr = &nav_pci->hli.btnit[0 * btns_per_group + button - 1]; + if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 2 && !(nav_pci->hli.hl_gi.btngr2_dsp_ty & 6)) + button_ptr = &nav_pci->hli.btnit[1 * btns_per_group + button - 1]; + if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 3 && !(nav_pci->hli.hl_gi.btngr3_dsp_ty & 6)) + button_ptr = &nav_pci->hli.btnit[2 * btns_per_group + button - 1]; + if (!button_ptr) { + xprintf(xine, XINE_VERBOSITY_DEBUG, + "libspudec: No suitable menu button group found, using group 1.\n"); + button_ptr = &nav_pci->hli.btnit[button - 1]; + } + + /* button areas in the nav packet are in screen coordinates, + * overlay clipping areas are in overlay coordinates; + * therefore we must subtract the display coordinates of the underlying overlay */ + overlay->hili_left = (button_ptr->x_start > base->x) ? (button_ptr->x_start - base->x) : 0; + overlay->hili_top = (button_ptr->y_start > base->y) ? (button_ptr->y_start - base->y) : 0; + overlay->hili_right = (button_ptr->x_end > base->x) ? (button_ptr->x_end - base->x) : 0; + overlay->hili_bottom = (button_ptr->y_end > base->y) ? (button_ptr->y_end - base->y) : 0; + if(button_ptr->btn_coln != 0) { +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: normal button clut\n"); +#endif + for (i = 0;i < 4; i++) { + overlay->hili_color[i] = clut[0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (16 + 4*i))]; + overlay->hili_trans[i] = 0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (4*i)); + } + } else { +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: abnormal button clut\n"); +#endif + for (i = 0;i < 4; i++) { +#ifdef LOG_BUTTON + printf("libspudec:btn_coln = 0, hili_color = color\n"); +#endif + overlay->hili_color[i] = overlay->color[i]; + overlay->hili_trans[i] = overlay->trans[i]; + } + } + + /* spudec_print_overlay( overlay ); */ +#ifdef LOG_BUTTON + printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n"); +#endif + + return 1; +} diff --git a/src/libspudec/spudec.h b/src/libspudec/spudec.h new file mode 100644 index 000000000..1e7d80596 --- /dev/null +++ b/src/libspudec/spudec.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * This file was originally part of the OMS program. + */ + +#ifndef __SPU_H__ +#define __SPU_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#ifdef HAVE_DVDNAV +# include +#else +# include "nav_types.h" +#endif + +#define NUM_SEQ_BUFFERS 50 +#define MAX_STREAMS 32 + +typedef struct spudec_clut_struct { +#ifdef WORDS_BIGENDIAN + uint8_t entry0 : 4; + uint8_t entry1 : 4; + uint8_t entry2 : 4; + uint8_t entry3 : 4; +#else + uint8_t entry1 : 4; + uint8_t entry0 : 4; + uint8_t entry3 : 4; + uint8_t entry2 : 4; +#endif +} spudec_clut_t; + +typedef struct { + uint8_t *buf; + uint32_t ra_offs; /* reassembly offset */ + uint32_t seq_len; + uint32_t buf_len; + uint32_t cmd_offs; + int64_t pts; /* Base PTS of this sequence */ + int32_t finished; /* Has this control sequence been finished? */ + uint32_t complete; /* Has this reassembly been finished? */ + uint32_t broken; /* this SPU is broken and should be dropped */ +} spudec_seq_t; + +typedef struct { + uint8_t *cmd_ptr; + + uint32_t field_offs[2]; + int32_t b_top, o_top; + int32_t b_bottom, o_bottom; + int32_t b_left, o_left; + int32_t b_right, o_right; + + int32_t modified; /* Was the sub-picture modified? */ + int32_t visible; /* Must the sub-picture be shown? */ + int32_t forced_display; /* This overlay is a menu */ + int32_t delay; /* Delay in 90Khz / 1000 */ + int32_t need_clut; /* doesn't have the right clut yet */ + int32_t cur_colors[4];/* current 4 colors been used */ + int32_t vobsub; /* vobsub must be aligned to bottom */ + + uint32_t clut[16]; +} spudec_state_t; + +typedef struct spudec_stream_state_s { + spudec_seq_t ra_seq; + spudec_state_t state; + int64_t vpts; + int64_t pts; + int32_t overlay_handle; +} spudec_stream_state_t; + +typedef struct { + spu_decoder_class_t decoder_class; +} spudec_class_t; + +typedef struct pci_node_s pci_node_t; +struct pci_node_s { + pci_t pci; + uint64_t vpts; + pci_node_t *next; +}; + +typedef struct spudec_decoder_s { + spu_decoder_t spu_decoder; + + spudec_class_t *class; + xine_stream_t *stream; + spudec_stream_state_t spudec_stream_state[MAX_STREAMS]; + + video_overlay_event_t event; + video_overlay_object_t object; + int32_t menu_handle; + + spudec_state_t state; + + vo_overlay_t overlay; + int ovl_caps; + int output_open; + pthread_mutex_t nav_pci_lock; + pci_node_t pci_cur; + uint32_t buttonN; /* Current button number for highlights */ + int32_t button_filter; /* Allow highlight changes or not */ + int64_t last_event_vpts; +} spudec_decoder_t; + +void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len); +void spudec_process( spudec_decoder_t *this, int stream_id); +/* the nav functions must be called with the nav_pci_lock held */ +void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf); +void spudec_clear_nav_list(spudec_decoder_t *this); +void spudec_update_nav(spudec_decoder_t *this); +void spudec_process_nav(spudec_decoder_t *this); +int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, int32_t button, int32_t mode, + vo_overlay_t * overlay, vo_overlay_t * base ); + +#endif diff --git a/src/libspudec/xine_spu_decoder.c b/src/libspudec/xine_spu_decoder.c index 7f0269dfb..e36b39fc8 100644 --- a/src/libspudec/xine_spu_decoder.c +++ b/src/libspudec/xine_spu_decoder.c @@ -33,7 +33,6 @@ #include #include "xine-engine/bswap.h" #include -#include "spu.h" #ifdef HAVE_DVDNAV # include # include @@ -42,6 +41,8 @@ # include "nav_types.h" #endif +#include "spudec.h" + /* #define LOG_DEBUG 1 #define LOG_BUTTON 1 -- cgit v1.2.3 From 09fedf23246bd7b622a362c57e34143cb7af32bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 10:55:55 +0100 Subject: Mark Annodex signature and its size static and constant. --- src/combined/xine_ogg_demuxer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/combined/xine_ogg_demuxer.c b/src/combined/xine_ogg_demuxer.c index ea03b5eec..edf98eb0a 100644 --- a/src/combined/xine_ogg_demuxer.c +++ b/src/combined/xine_ogg_demuxer.c @@ -1960,8 +1960,8 @@ static int detect_anx_content (int detection_method, demux_class_t *class_gen, case METHOD_BY_CONTENT: { uint8_t buf[ANNODEX_SIGNATURE_SEARCH]; int found_annodex_signature = 0; - const char *annodex_signature = "Annodex"; - int annodex_signature_length = 7; /* = strlen(annodex_signature) */ + static const char annodex_signature[] = "Annodex"; + static const int annodex_signature_length = 7; /* = strlen(annodex_signature) */ int i, j; if (_x_demux_read_header(input, buf, ANNODEX_SIGNATURE_SEARCH) != -- cgit v1.2.3 From 9c1838e38617700364b63d3c2ed99bc54461d4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 10:59:29 +0100 Subject: Use memmem to search for the Annodex string, rather than reimplementing it by hand. --- src/combined/xine_ogg_demuxer.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/combined/xine_ogg_demuxer.c b/src/combined/xine_ogg_demuxer.c index edf98eb0a..159f4b662 100644 --- a/src/combined/xine_ogg_demuxer.c +++ b/src/combined/xine_ogg_demuxer.c @@ -1959,32 +1959,14 @@ static int detect_anx_content (int detection_method, demux_class_t *class_gen, case METHOD_BY_CONTENT: { uint8_t buf[ANNODEX_SIGNATURE_SEARCH]; - int found_annodex_signature = 0; - static const char annodex_signature[] = "Annodex"; - static const int annodex_signature_length = 7; /* = strlen(annodex_signature) */ - int i, j; if (_x_demux_read_header(input, buf, ANNODEX_SIGNATURE_SEARCH) != ANNODEX_SIGNATURE_SEARCH) return 0; /* scan for 'Annodex' signature in the first 64 bytes */ - for (i = 0, j = 0; i < ANNODEX_SIGNATURE_SEARCH; i++) { - if (buf[i] == annodex_signature[j]) { - if (j >= annodex_signature_length) { - /* found signature */ - found_annodex_signature = 1; - break; - } else { - j++; - } - } - } - - if (found_annodex_signature) - return 1; - else - return 0; + return !!memmem(buf, ANNODEX_SIGNATURE_SEARCH, + "Annodex", sizeof("Annodex")-1); } #undef ANNODEX_SIGNATURE_SEARCH -- cgit v1.2.3 From c73bb43275bce8b704c86533a4fdade9d64a28f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:07:29 +0100 Subject: Make buffering and enabled static, also use them as array of char array rather than array of pointers. --- src/input/net_buf_ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c index 624af4081..aaf575e40 100644 --- a/src/input/net_buf_ctrl.c +++ b/src/input/net_buf_ctrl.c @@ -118,8 +118,8 @@ void nbc_check_buffers (nbc_t *this) { } static void display_stats (nbc_t *this) { - const char *buffering[2] = {" ", "buf"}; - const char *enabled[2] = {"off", "on "}; + static const char buffering[2][4] = {" ", "buf"}; + static const char enabled[2][4] = {"off", "on "}; printf("bufing: %d, enb: %d\n", this->buffering, this->enabled); printf("net_buf_ctrl: vid %3d%% %4.1fs %4" PRId64 "kbps %1d, "\ -- cgit v1.2.3 From 353b351017e8de11269112e621911d891ed7a305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:14:30 +0100 Subject: Mark content static and const. --- src/input/input_dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 1151d9a81..4f66b8ff4 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -1591,7 +1591,7 @@ static void load_epg_data(dvb_input_plugin_t *this) case 0x54: { /* Content Descriptor, riveting stuff */ int content_bits = getbits(eit, 8, 4); - char *content[] = { + static const char *content[] = { "UNKNOWN","MOVIE","NEWS","ENTERTAINMENT","SPORT", "CHILDRENS","MUSIC","ARTS/CULTURE","CURRENT AFFAIRS", "EDUCATIONAL","INFOTAINMENT","SPECIAL","COMEDY","DRAMA", -- cgit v1.2.3 From 64cd8ba42517cdbb58f7526e7bcbe447fccf22bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:15:37 +0100 Subject: Mark the name attribute of Param being a const char *. --- src/input/input_dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 4f66b8ff4..fe4e7de5a 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -359,7 +359,7 @@ typedef struct { } dvb_input_plugin_t; typedef struct { - char *name; + const char *name; int value; } Param; -- cgit v1.2.3 From d4a43f8c11da38b9bd6fa54476d08efb4bff6fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:25:37 +0100 Subject: Use asprintf rather than snprintf, make frontend_device a local variable, and make sure to free the allocated variables on error. --- src/input/input_dvb.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index fe4e7de5a..1e876f251 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -234,9 +234,8 @@ typedef struct { int adapter_num; - char frontend_device[100]; - char dvr_device[100]; - char demux_device[100]; + char *dvr_device; + char *demux_device; struct dmx_pes_filter_params pesFilterParams[MAX_FILTERS]; struct dmx_pes_filter_params subFilterParams[MAX_SUBTITLES]; @@ -548,9 +547,10 @@ static void tuner_dispose(tuner_t * this) for (x = 0; x < MAX_SUBTITLES; x++) if (this->fd_subfilter[x] >= 0) close(this->fd_subfilter[x]); - - if(this) - free(this); + + free(this->dvr_device); + free(this->demux_device); + free(this); } @@ -560,7 +560,8 @@ static tuner_t *tuner_init(xine_t * xine, int adapter) tuner_t *this; int x; int test_video; - char *video_device=xine_xmalloc(200); + char *video_device = NULL; + char *frontend_device = NULL; _x_assert(video_device != NULL); @@ -576,21 +577,24 @@ static tuner_t *tuner_init(xine_t * xine, int adapter) this->xine = xine; this->adapter_num = adapter; - snprintf(this->frontend_device,100,"/dev/dvb/adapter%i/frontend0",this->adapter_num); - snprintf(this->demux_device,100,"/dev/dvb/adapter%i/demux0",this->adapter_num); - snprintf(this->dvr_device,100,"/dev/dvb/adapter%i/dvr0",this->adapter_num); - snprintf(video_device,100,"/dev/dvb/adapter%i/video0",this->adapter_num); - - if ((this->fd_frontend = open(this->frontend_device, O_RDWR)) < 0) { + asprintf(&this->demux_device,"/dev/dvb/adapter%i/demux0",this->adapter_num); + asprintf(&this->dvr_device,"/dev/dvb/adapter%i/dvr0",this->adapter_num); + asprintf(&video_device,"/dev/dvb/adapter%i/video0",this->adapter_num); + + asprintf(&frontend_device,"/dev/dvb/adapter%i/frontend0",this->adapter_num); + if ((this->fd_frontend = open(frontend_device, O_RDWR)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FRONTEND DEVICE: %s\n", strerror(errno)); tuner_dispose(this); - return NULL; + this = NULL; + goto exit; } + free(frontend_device); frontend_device = NULL; if ((ioctl(this->fd_frontend, FE_GET_INFO, &this->feinfo)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FE_GET_INFO: %s\n", strerror(errno)); tuner_dispose(this); - return NULL; + this = NULL; + goto exit; } for (x = 0; x < MAX_FILTERS; x++) { @@ -598,7 +602,8 @@ static tuner_t *tuner_init(xine_t * xine, int adapter) if (this->fd_pidfilter[x] < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "DEMUX DEVICE PIDfilter: %s\n", strerror(errno)); tuner_dispose(this); - return NULL; + this = NULL; + goto exit; } } for (x = 0; x < MAX_SUBTITLES; x++) { @@ -630,7 +635,9 @@ static tuner_t *tuner_init(xine_t * xine, int adapter) close(test_video); } + exit: free(video_device); + free(frontend_device); return this; } -- cgit v1.2.3 From f78fe11dba3b7bea57679b1deeead2929b7175c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:27:13 +0100 Subject: Mark handled_mrl const and make it a char array. Use sizeof rather than strlen. --- src/input/input_dvd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index 8656097bc..e3b9ed091 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -1621,12 +1621,12 @@ static int dvd_plugin_open (input_plugin_t *this_gen) { static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *data) { dvd_input_plugin_t *this; dvd_input_class_t *class = (dvd_input_class_t*)class_gen; - static char *handled_mrl = "dvd:/"; + static const char handled_mrl[] = "dvd:/"; trace_print("Called\n"); /* Check we can handle this MRL */ - if (strncasecmp (data, handled_mrl, strlen(handled_mrl) ) != 0) + if (strncasecmp (data, handled_mrl, sizeof(handled_mrl)-1 ) != 0) return NULL; this = (dvd_input_plugin_t *) xine_xmalloc (sizeof (dvd_input_plugin_t)); -- cgit v1.2.3 From 4dffcd03d2d408a1536212f3a596560354878eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:33:20 +0100 Subject: Mark tv_standard_names and tv_standard_value static. --- src/input/input_v4l.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index ff9ea87d0..34ebcdc27 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -110,8 +110,8 @@ static const resolution_t resolutions[] = { { 160, 120 } }; -static char *tv_standard_names[] = { "PAL", "NTSC", "SECAM", NULL }; -static int tv_standard_values[] = { VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM }; +static const char *tv_standard_names[] = { "PAL", "NTSC", "SECAM", NULL }; +static const int tv_standard_values[] = { VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM }; #define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0])) #define RADIO_DEV "/dev/v4l/radio0" -- cgit v1.2.3 From 8005bb8cb115245bfa8770fb18c242ba35d38d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:35:07 +0100 Subject: Mark static strings as const. --- src/libmpeg2/stats.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libmpeg2/stats.c b/src/libmpeg2/stats.c index 04de526f1..d594e718d 100644 --- a/src/libmpeg2/stats.c +++ b/src/libmpeg2/stats.c @@ -51,7 +51,7 @@ static int debug_is_on (void) static void stats_picture (uint8_t * buffer) { - static char * picture_coding_type_str [8] = { + static const char * picture_coding_type_str [8] = { "Invalid picture type", "I-type", "P-type", @@ -81,7 +81,7 @@ static void stats_user_data (uint8_t * buffer) static void stats_sequence (uint8_t * buffer) { - static char * aspect_ratio_information_str[8] = { + static const char * aspect_ratio_information_str[8] = { "Invalid Aspect Ratio", "1:1", "4:3", @@ -91,7 +91,7 @@ static void stats_sequence (uint8_t * buffer) "Invalid Aspect Ratio", "Invalid Aspect Ratio" }; - static char * frame_rate_str[16] = { + static const char * frame_rate_str[16] = { "Invalid frame_rate_code", "23.976", "24", "25" , "29.97", "30" , "50", "59.94", "60" , @@ -159,7 +159,7 @@ static void stats_slice (int code, uint8_t * buffer) static void stats_sequence_extension (uint8_t * buffer) { - static char * chroma_format_str[4] = { + static const char * chroma_format_str[4] = { "Invalid Chroma Format", "4:2:0 Chroma", "4:2:2 Chroma", @@ -204,7 +204,7 @@ static void stats_picture_display_extension (uint8_t * buffer) static void stats_picture_coding_extension (uint8_t * buffer) { - static char * picture_structure_str[4] = { + static const char * picture_structure_str[4] = { "Invalid Picture Structure", "Top field", "Bottom field", -- cgit v1.2.3 From b2a5768b9d0d2578def747bdb6f872c97a4723cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:37:03 +0100 Subject: Mark static strings as const. --- src/post/planar/noise.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c index afe05b180..57b8618ab 100644 --- a/src/post/planar/noise.c +++ b/src/post/planar/noise.c @@ -318,8 +318,8 @@ typedef struct noise_parameters_s { type, quality, pattern; } noise_parameters_t; -static char *enum_types[] = {"uniform", "gaussian", NULL}; -static char *enum_quality[] = {"fixed", "temporal", "averaged temporal", NULL}; +static const char *enum_types[] = {"uniform", "gaussian", NULL}; +static const char *enum_quality[] = {"fixed", "temporal", "averaged temporal", NULL}; /* * description of params struct -- cgit v1.2.3 From b6aea3d60f27a423058f6cf0da674fba4ce505ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:40:44 +0100 Subject: Rewrite get_help function to use asprintf, without declaring the two help1/help2 strings and without running two gettext() calls at every get_help() call. --- src/post/planar/pp.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/post/planar/pp.c b/src/post/planar/pp.c index 3f9c0d745..1213c82df 100644 --- a/src/post/planar/pp.c +++ b/src/post/planar/pp.c @@ -20,6 +20,8 @@ * plugin for ffmpeg libpostprocess */ +#include + #include "xine_internal.h" #include "post.h" #include "xineutils.h" @@ -102,23 +104,18 @@ static xine_post_api_descr_t * get_param_descr (void) { } static char * get_help (void) { - char *help1 = - _("FFmpeg libpostprocess plugin.\n" - "\n" - "Parameters\n" - "\n"); - - char *help2 = - _("\n" - "* libpostprocess (C) Michael Niedermayer\n" - ); static char *help = NULL; if( !help ) { - help = malloc( strlen(help1) + strlen(help2) + strlen(pp_help) + 1); - strcpy(help, help1); - strcat(help, pp_help); - strcat(help, help2); + asprintf(&help, "%s%s%s", + _("FFmpeg libpostprocess plugin.\n" + "\n" + "Parameters\n" + "\n"), + pp_help, + _("\n" + "* libpostprocess (C) Michael Niedermayer\n") + ); } return help; } -- cgit v1.2.3 From 91c06ff0cf45fc30ff3fb6f76d1c9b6c63e59d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 11:43:14 +0100 Subject: Mark static strings as const. --- src/xine-engine/configfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 2f5e6214a..69f9ed6f9 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -207,7 +207,7 @@ static const xine_config_entry_translation_t config_entry_translation[] = { static int config_section_enum(const char *sect) { - static char *known_section[] = { + static const char *const known_section[] = { "gui", "ui", "audio", -- cgit v1.2.3 From 441dab939754324fa760627c133dee1b0125c213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 15:06:43 +0100 Subject: Remove orphaned functions. --- src/demuxers/demux_flv.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c index 7f9dec5fe..131470a3e 100644 --- a/src/demuxers/demux_flv.c +++ b/src/demuxers/demux_flv.c @@ -870,30 +870,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static const char *get_description (demux_class_t *this_gen) { - return "Flash Video file demux plugin"; -} - -static const char *get_identifier (demux_class_t *this_gen) { - return "FLV"; -} - -static const char *get_extensions (demux_class_t *this_gen) { - return "flv"; -} - -static const char *get_mimetypes (demux_class_t *this_gen) { - return "video/x-flv: flv: Flash video;" - "video/flv: flv: Flash video;" - "application/x-flash-video: flv: Flash video;"; -} - -static void class_dispose (demux_class_t *this_gen) { - demux_flv_class_t *this = (demux_flv_class_t *) this_gen; - - free (this); -} - static void *init_plugin (xine_t *xine, void *data) { demux_flv_class_t *this; -- cgit v1.2.3 From 0bd997bff81387d188a3368dea6b27c9c39d3deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 15:11:28 +0100 Subject: Transform mmst_proto_s and mmsh_proto_s into arrays of arrays, padded at 8 bytes. The size occupied will be smaller in 64-bit systems, and almost the same in 32-bit systems, but the access should be faster. --- src/input/mms.c | 4 ++-- src/input/mmsh.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/input/mms.c b/src/input/mms.c index f11a89cf3..7b8e18bab 100644 --- a/src/input/mms.c +++ b/src/input/mms.c @@ -532,7 +532,7 @@ static int interp_asf_header (mms_t *this) { return 1; } -static const char *const mmst_proto_s[] = { "mms", "mmst", NULL }; +static const char mmst_proto_s[][8] = { "mms", "mmst", "" }; static int mmst_valid_proto (char *proto) { int i = 0; @@ -542,7 +542,7 @@ static int mmst_valid_proto (char *proto) { if (!proto) return 0; - while(mmst_proto_s[i]) { + while(*(mmst_proto_s[i])) { if (!strcasecmp(proto, mmst_proto_s[i])) { return 1; } diff --git a/src/input/mmsh.c b/src/input/mmsh.c index ae1c62bc1..13b51d21e 100644 --- a/src/input/mmsh.c +++ b/src/input/mmsh.c @@ -447,7 +447,7 @@ static int interp_header (mmsh_t *this) { return 1; } -static const char *const mmsh_proto_s[] = { "mms", "mmsh", NULL }; +static const char mmsh_proto_s[][8] = { "mms", "mmsh", "" }; static int mmsh_valid_proto (char *proto) { int i = 0; @@ -457,7 +457,7 @@ static int mmsh_valid_proto (char *proto) { if (!proto) return 0; - while(mmsh_proto_s[i]) { + while(*(mmsh_proto_s[i])) { if (!strcasecmp(proto, mmsh_proto_s[i])) { return 1; } -- cgit v1.2.3 From e387e33000e17bda5b1c4e29a545b1cc60618342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 15:14:18 +0100 Subject: Transform ignore_scheme into an array of arrays, padded at 8 bytes. --- src/input/input_gnome_vfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c index 71a4ada85..ad756e7e7 100644 --- a/src/input/input_gnome_vfs.c +++ b/src/input/input_gnome_vfs.c @@ -291,7 +291,7 @@ gnomevfs_klass_dispose (input_class_t *this_gen) g_free (this); } -static const char *const ignore_scheme[] = { "cdda", "file", "http" }; +static const char ignore_scheme[][8] = { "cdda", "file", "http" }; static input_plugin_t * gnomevfs_klass_get_instance (input_class_t *klass_gen, xine_stream_t *stream, -- cgit v1.2.3 From 63ba5c5f0504600844f9a9e50b9d7da3b10953f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 19:29:34 +0100 Subject: Mark more arrays as constant. --- src/input/input_dvb.c | 2 +- src/input/input_v4l.c | 2 +- src/libmpeg2/stats.c | 10 +++++----- src/libspucc/cc_decoder.h | 2 +- src/post/deinterlace/xine_plugin.c | 4 ++-- src/post/planar/noise.c | 4 ++-- src/xine-engine/osd.h | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 1e876f251..e6daf423b 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -1598,7 +1598,7 @@ static void load_epg_data(dvb_input_plugin_t *this) case 0x54: { /* Content Descriptor, riveting stuff */ int content_bits = getbits(eit, 8, 4); - static const char *content[] = { + static const char *const content[] = { "UNKNOWN","MOVIE","NEWS","ENTERTAINMENT","SPORT", "CHILDRENS","MUSIC","ARTS/CULTURE","CURRENT AFFAIRS", "EDUCATIONAL","INFOTAINMENT","SPECIAL","COMEDY","DRAMA", diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index 34ebcdc27..7af8788ff 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -110,7 +110,7 @@ static const resolution_t resolutions[] = { { 160, 120 } }; -static const char *tv_standard_names[] = { "PAL", "NTSC", "SECAM", NULL }; +static const char *const tv_standard_names[] = { "PAL", "NTSC", "SECAM", NULL }; static const int tv_standard_values[] = { VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM }; #define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0])) diff --git a/src/libmpeg2/stats.c b/src/libmpeg2/stats.c index d594e718d..63c701179 100644 --- a/src/libmpeg2/stats.c +++ b/src/libmpeg2/stats.c @@ -51,7 +51,7 @@ static int debug_is_on (void) static void stats_picture (uint8_t * buffer) { - static const char * picture_coding_type_str [8] = { + static const char *const picture_coding_type_str [8] = { "Invalid picture type", "I-type", "P-type", @@ -81,7 +81,7 @@ static void stats_user_data (uint8_t * buffer) static void stats_sequence (uint8_t * buffer) { - static const char * aspect_ratio_information_str[8] = { + static const char *const aspect_ratio_information_str[8] = { "Invalid Aspect Ratio", "1:1", "4:3", @@ -91,7 +91,7 @@ static void stats_sequence (uint8_t * buffer) "Invalid Aspect Ratio", "Invalid Aspect Ratio" }; - static const char * frame_rate_str[16] = { + static const char *const frame_rate_str[16] = { "Invalid frame_rate_code", "23.976", "24", "25" , "29.97", "30" , "50", "59.94", "60" , @@ -159,7 +159,7 @@ static void stats_slice (int code, uint8_t * buffer) static void stats_sequence_extension (uint8_t * buffer) { - static const char * chroma_format_str[4] = { + static const char *const chroma_format_str[4] = { "Invalid Chroma Format", "4:2:0 Chroma", "4:2:2 Chroma", @@ -204,7 +204,7 @@ static void stats_picture_display_extension (uint8_t * buffer) static void stats_picture_coding_extension (uint8_t * buffer) { - static const char * picture_structure_str[4] = { + static const char *const picture_structure_str[4] = { "Invalid Picture Structure", "Top field", "Bottom field", diff --git a/src/libspucc/cc_decoder.h b/src/libspucc/cc_decoder.h index 8698189a6..3924bb8be 100644 --- a/src/libspucc/cc_decoder.h +++ b/src/libspucc/cc_decoder.h @@ -31,7 +31,7 @@ typedef struct cc_decoder_s cc_decoder_t; typedef struct cc_renderer_s cc_renderer_t; #define NUM_CC_PALETTES 2 -static const char *cc_schemes[NUM_CC_PALETTES + 1] = { +static const char *const cc_schemes[NUM_CC_PALETTES + 1] = { "White/Gray/Translucent", "White/Black/Solid", NULL diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c index 68eabba67..6ae2bd96d 100644 --- a/src/post/deinterlace/xine_plugin.c +++ b/src/post/deinterlace/xine_plugin.c @@ -56,8 +56,8 @@ typedef struct post_plugin_deinterlace_s post_plugin_deinterlace_t; #define MAX_NUM_METHODS 30 static const char *enum_methods[MAX_NUM_METHODS]; -static const char *enum_pulldown[] = { "none", "vektor", NULL }; -static const char *enum_framerate[] = { "full", "half_top", "half_bottom", NULL }; +static const char *const enum_pulldown[] = { "none", "vektor", NULL }; +static const char *const enum_framerate[] = { "full", "half_top", "half_bottom", NULL }; static void *help_string; diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c index 57b8618ab..4ca3d62dc 100644 --- a/src/post/planar/noise.c +++ b/src/post/planar/noise.c @@ -318,8 +318,8 @@ typedef struct noise_parameters_s { type, quality, pattern; } noise_parameters_t; -static const char *enum_types[] = {"uniform", "gaussian", NULL}; -static const char *enum_quality[] = {"fixed", "temporal", "averaged temporal", NULL}; +static const char *const enum_types[] = {"uniform", "gaussian", NULL}; +static const char *const enum_quality[] = {"fixed", "temporal", "averaged temporal", NULL}; /* * description of params struct diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h index 7b04c0a17..ce7c13e5f 100644 --- a/src/xine-engine/osd.h +++ b/src/xine-engine/osd.h @@ -265,7 +265,7 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ); #ifdef __OSD_C__ /* This text descriptions are used for config screen */ -static const char *textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { +static const char *const textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { "white-black-transparent", "white-none-transparent", "white-none-translucid", -- cgit v1.2.3 From b67f71f5b1d9a869d0adf5609baa9670a112bcf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 19 Dec 2007 19:46:12 +0100 Subject: Move code out of osd.h that was present only with __OSD_C__ defined. --- src/xine-engine/osd.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++- src/xine-engine/osd.h | 102 -------------------------------------------------- 2 files changed, 95 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 1587b76e4..23c1cb35e 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -20,8 +20,6 @@ * OSD stuff (text and graphic primitives) */ -#define __OSD_C__ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -50,6 +48,7 @@ #define XINE_ENGINE_INTERNAL +#include "alphablend.h" #include "xine_internal.h" #include "xine-engine/bswap.h" #include "xineutils.h" @@ -110,6 +109,100 @@ # define FT_LOAD_FLAGS (FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING) #endif +/* This text descriptions are used for config screen */ +static const char *const textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { + "white-black-transparent", + "white-none-transparent", + "white-none-translucid", + "yellow-black-transparent", + NULL}; + +/* + Palette entries as used by osd fonts: + + 0: not used by font, always transparent + 1: font background, usually transparent, may be used to implement + translucid boxes where the font will be printed. + 2-5: transition between background and border (usually only alpha + value changes). + 6: font border. if the font is to be displayed without border this + will probably be adjusted to font background or near. + 7-9: transition between border and foreground + 10: font color (foreground) +*/ + +/* + The palettes below were made by hand, ie, i just throw + values that seemed to do the transitions i wanted. + This can surelly be improved a lot. [Miguel] +*/ + +static const clut_t textpalettes_color[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { +/* white, black border, transparent */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0x40, 0x80, 0x80), /*7*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*8*/ + CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ + }, + /* white, no border, transparent */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*7*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*8*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ + }, + /* white, no border, translucid */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0xa0, 0x80, 0x80), /*7*/ + CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*8*/ + CLUT_Y_CR_CB_INIT(0xe0, 0x80, 0x80), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ + }, + /* yellow, black border, transparent */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0x40, 0x84, 0x60), /*7*/ + CLUT_Y_CR_CB_INIT(0x70, 0x88, 0x40), /*8*/ + CLUT_Y_CR_CB_INIT(0xb0, 0x8a, 0x20), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00), /*10*/ + }, +}; + +static const uint8_t textpalettes_trans[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { + {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, + {0, 0, 0, 0, 0, 0, 2, 6, 9, 12, 15 }, + {0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }, + {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, +}; + typedef struct osd_fontchar_s { uint8_t *bmp; uint16_t code; diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h index ce7c13e5f..ed4e2434b 100644 --- a/src/xine-engine/osd.h +++ b/src/xine-engine/osd.h @@ -29,9 +29,6 @@ #ifdef XINE_COMPILE # include "video_overlay.h" -# ifdef __OSD_C__ -# include "alphablend.h" -# endif #else # include #endif @@ -262,104 +259,5 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ); #define TEXTPALETTE_WHITE_NONE_TRANSLUCID 2 #define TEXTPALETTE_YELLOW_BLACK_TRANSPARENT 3 -#ifdef __OSD_C__ - -/* This text descriptions are used for config screen */ -static const char *const textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { - "white-black-transparent", - "white-none-transparent", - "white-none-translucid", - "yellow-black-transparent", - NULL}; - - -/* - Palette entries as used by osd fonts: - - 0: not used by font, always transparent - 1: font background, usually transparent, may be used to implement - translucid boxes where the font will be printed. - 2-5: transition between background and border (usually only alpha - value changes). - 6: font border. if the font is to be displayed without border this - will probably be adjusted to font background or near. - 7-9: transition between border and foreground - 10: font color (foreground) -*/ - -/* - The palettes below were made by hand, ie, i just throw - values that seemed to do the transitions i wanted. - This can surelly be improved a lot. [Miguel] -*/ - -static const clut_t textpalettes_color[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { -/* white, black border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0x40, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* white, no border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* white, no border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0xa0, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xe0, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* yellow, black border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0x40, 0x84, 0x60), /*7*/ - CLUT_Y_CR_CB_INIT(0x70, 0x88, 0x40), /*8*/ - CLUT_Y_CR_CB_INIT(0xb0, 0x8a, 0x20), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00), /*10*/ - }, -}; - -static const uint8_t textpalettes_trans[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { - {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, - {0, 0, 0, 0, 0, 0, 2, 6, 9, 12, 15 }, - {0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }, - {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, -}; - -#endif /* __OSD_C__ */ - #endif -- cgit v1.2.3 From d92d390d8f4cf6198c36e88af9bbadc203ca49d6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Thu, 20 Dec 2007 23:04:55 +0000 Subject: Correct some #includes. --- src/dxr3/video_out_dxr3.h | 2 +- src/input/vcd/xine-extra.h | 2 +- src/video_out/xxmc.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h index a5a1368a3..b3c607109 100644 --- a/src/dxr3/video_out_dxr3.h +++ b/src/dxr3/video_out_dxr3.h @@ -27,7 +27,7 @@ #endif #include -#include "vo_scale.h" +#include #include "dxr3_scr.h" #include "dxr3.h" diff --git a/src/input/vcd/xine-extra.h b/src/input/vcd/xine-extra.h index 4246405ba..59f562cbd 100644 --- a/src/input/vcd/xine-extra.h +++ b/src/input/vcd/xine-extra.h @@ -37,7 +37,7 @@ /* Xine includes */ #include -#include "input_plugin.h" +#include #include /*! diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h index d6cd7e514..9aea10854 100644 --- a/src/video_out/xxmc.h +++ b/src/video_out/xxmc.h @@ -86,7 +86,7 @@ #include #include #include -#include "vo_scale.h" +#include #include "x11osd.h" #include "accel_xvmc.h" -- cgit v1.2.3 From 13ceff6eca6ec498ea21738fd83744b218f8e636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 00:38:00 +0100 Subject: Always enable a52dec capabilities for external a52dec. This make it possible to use the DJB accelerated FFT when using the external a52dec liba52 library. --HG-- extra : transplant_source : %03Y%0F%8C%F0%05%EE%F7%5E%2B%A9u%7D%96%F8%D2%13%CD%F4%9D --- src/liba52/xine_a52_decoder.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/liba52/xine_a52_decoder.c b/src/liba52/xine_a52_decoder.c index 6c4442996..b8b500ecd 100644 --- a/src/liba52/xine_a52_decoder.c +++ b/src/liba52/xine_a52_decoder.c @@ -673,8 +673,25 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre this->pts_list[0] = 0; this->pts_list_position = 0; - if( !this->a52_state ) - this->a52_state = a52_init (xine_mm_accel()); + if( !this->a52_state ) { + this->a52_state = +#ifdef HAVE_A52DEC_A52_H /* External liba52 */ + /* When using external liba52, enable _all_ capabilities, even + if that might break stuff if they add some new capability + that depends on CPU's caps. + At the moment the only capability is DJBFFT, which is tested + only if djbfft is being used at compile time. + + The actual question would be: why don't they check for + capabilities themselves? + */ +#warning "Enabling all external liba52 capabilities." + a52_init (0xFFFFFFFF) +#else + a52_init (xine_mm_accel()) +#endif + ; + } /* * find out if this driver supports a52 output -- cgit v1.2.3 From 3a217974c83b61f59a8a86684802864d4f9e03d6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Fri, 21 Dec 2007 23:59:48 +0000 Subject: More #include fixes. --- src/libw32dll/wine/debugtools.h | 2 +- src/libw32dll/wine/ext.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libw32dll/wine/debugtools.h b/src/libw32dll/wine/debugtools.h index 3b342e10c..c6fac518d 100644 --- a/src/libw32dll/wine/debugtools.h +++ b/src/libw32dll/wine/debugtools.h @@ -8,7 +8,7 @@ #include "config.h" #include "windef.h" -#include "compat.h" +#include struct _GUID; diff --git a/src/libw32dll/wine/ext.h b/src/libw32dll/wine/ext.h index f0f505c4d..ad22edc5e 100644 --- a/src/libw32dll/wine/ext.h +++ b/src/libw32dll/wine/ext.h @@ -2,7 +2,7 @@ #define loader_ext_h #include "windef.h" -#include "attributes.h" +#include extern LPVOID FILE_dommap( int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, -- cgit v1.2.3 From 9b3fc5f500954e2deb241c17b0437ec8afad025e Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sat, 22 Dec 2007 15:48:51 +0000 Subject: Remove an assertion which is always triggered. --- src/input/input_dvb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index e6daf423b..5ba3f9d93 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -563,8 +563,6 @@ static tuner_t *tuner_init(xine_t * xine, int adapter) char *video_device = NULL; char *frontend_device = NULL; - _x_assert(video_device != NULL); - this = (tuner_t *) xine_xmalloc(sizeof(tuner_t)); _x_assert(this != NULL); -- cgit v1.2.3 From 6dc39d73d23ca2bfb2f6784e303c7c97e00414e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 23:01:01 +0100 Subject: Rename libxineadec directory in audio_dec. --HG-- rename : src/libxineadec/Makefile.am => src/audio_dec/Makefile.am rename : src/libxineadec/fooaudio.c => src/audio_dec/fooaudio.c rename : src/libxineadec/gsm610.c => src/audio_dec/gsm610.c rename : src/libxineadec/xine_a52_decoder.c => src/audio_dec/xine_a52_decoder.c rename : src/libxineadec/xine_dts_decoder.c => src/audio_dec/xine_dts_decoder.c rename : src/libxineadec/xine_faad_decoder.c => src/audio_dec/xine_faad_decoder.c rename : src/libxineadec/xine_lpcm_decoder.c => src/audio_dec/xine_lpcm_decoder.c rename : src/libxineadec/xine_mad_decoder.c => src/audio_dec/xine_mad_decoder.c rename : src/libxineadec/xine_musepack_decoder.c => src/audio_dec/xine_musepack_decoder.c --- src/Makefile.am | 2 +- src/audio_dec/Makefile.am | 85 ++++ src/audio_dec/fooaudio.c | 336 +++++++++++++ src/audio_dec/gsm610.c | 281 +++++++++++ src/audio_dec/xine_a52_decoder.c | 849 ++++++++++++++++++++++++++++++++ src/audio_dec/xine_dts_decoder.c | 578 ++++++++++++++++++++++ src/audio_dec/xine_faad_decoder.c | 477 ++++++++++++++++++ src/audio_dec/xine_lpcm_decoder.c | 278 +++++++++++ src/audio_dec/xine_mad_decoder.c | 365 ++++++++++++++ src/audio_dec/xine_musepack_decoder.c | 462 +++++++++++++++++ src/libxineadec/Makefile.am | 85 ---- src/libxineadec/fooaudio.c | 336 ------------- src/libxineadec/gsm610.c | 281 ----------- src/libxineadec/xine_a52_decoder.c | 849 -------------------------------- src/libxineadec/xine_dts_decoder.c | 578 ---------------------- src/libxineadec/xine_faad_decoder.c | 477 ------------------ src/libxineadec/xine_lpcm_decoder.c | 278 ----------- src/libxineadec/xine_mad_decoder.c | 365 -------------- src/libxineadec/xine_musepack_decoder.c | 462 ----------------- 19 files changed, 3712 insertions(+), 3712 deletions(-) create mode 100644 src/audio_dec/Makefile.am create mode 100644 src/audio_dec/fooaudio.c create mode 100644 src/audio_dec/gsm610.c create mode 100644 src/audio_dec/xine_a52_decoder.c create mode 100644 src/audio_dec/xine_dts_decoder.c create mode 100644 src/audio_dec/xine_faad_decoder.c create mode 100644 src/audio_dec/xine_lpcm_decoder.c create mode 100644 src/audio_dec/xine_mad_decoder.c create mode 100644 src/audio_dec/xine_musepack_decoder.c delete mode 100644 src/libxineadec/Makefile.am delete mode 100644 src/libxineadec/fooaudio.c delete mode 100644 src/libxineadec/gsm610.c delete mode 100644 src/libxineadec/xine_a52_decoder.c delete mode 100644 src/libxineadec/xine_dts_decoder.c delete mode 100644 src/libxineadec/xine_faad_decoder.c delete mode 100644 src/libxineadec/xine_lpcm_decoder.c delete mode 100644 src/libxineadec/xine_mad_decoder.c delete mode 100644 src/libxineadec/xine_musepack_decoder.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 256e28bfa..816cfa07c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,7 @@ SUBDIRS = \ xine-utils \ xine-engine \ audio_out \ + audio_dec \ video_out \ dxr3 \ input \ @@ -18,7 +19,6 @@ SUBDIRS = \ libsputext \ libw32dll \ libxinevdec \ - libxineadec \ libreal \ post \ combined \ diff --git a/src/audio_dec/Makefile.am b/src/audio_dec/Makefile.am new file mode 100644 index 000000000..a85497bbf --- /dev/null +++ b/src/audio_dec/Makefile.am @@ -0,0 +1,85 @@ +include $(top_srcdir)/misc/Makefile.common + +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) +AM_LDFLAGS = $(xineplug_ldflags) + +EXTRA_DIST = fooaudio.c + +if ENABLE_MUSEPACK +musepack_module = xineplug_decode_mpc.la +endif + +if ENABLE_DTS +dts_module = xineplug_decode_dts.la +endif + +if ENABLE_MAD +mad_module = xineplug_decode_mad.la +endif + +if ENABLE_A52DEC +a52_module = xineplug_decode_a52.la +endif + +if ENABLE_FAAD +faad_module = xineplug_decode_faad.la +endif + +$(top_builddir)/contrib/a52dec/liba52.la: + $(MAKE) -C $(top_builddir)/contrib/a52dec + +$(top_builddir)/contrib/libfaad/libfaad.la: + $(MAKE) -C $(top_builddir)/contrib/libfaad + +$(top_builddir)/contrib/libmad/libmad.la: + $(MAKE) -C $(top_builddir)/contrib/libmad + +$(top_builddir)/contrib/libmpcdec/libmpcdec.la: + $(MAKE) -C $(top_builddir)/contrib/libmpcdec + +$(top_builddir)/contrib/libdca/libdca.la: + $(MAKE) -C $(top_builddir)/contrib/libdca + +$(top_builddir)/contrib/gsm610/libgsm610.la: + $(MAKE) -C $(top_builddir)/contrib/gsm610 + +xineplug_LTLIBRARIES = \ + xineplug_decode_gsm610.la \ + xineplug_decode_lpcm.la \ + $(musepack_module) \ + $(dts_module) \ + $(mad_module) \ + $(a52_module) \ + $(faad_module) + +xineplug_decode_gsm610_la_SOURCES = gsm610.c +xineplug_decode_gsm610_la_LIBADD = $(XINE_LIB) $(top_builddir)/contrib/gsm610/libgsm610.la +xineplug_decode_gsm610_la_CPPFLAGS = -I$(top_srcdir)/contrib/gsm610 + +xineplug_decode_lpcm_la_SOURCES = xine_lpcm_decoder.c +xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB) + +xineplug_decode_mpc_la_SOURCES = xine_musepack_decoder.c +xineplug_decode_mpc_la_DEPENDENCIES = $(MPCDEC_DEPS) +xineplug_decode_mpc_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(MPCDEC_LIBS) +xineplug_decode_mpc_la_CFLAGS = $(AM_CFLAGS) $(MPCDEC_CFLAGS) + +xineplug_decode_dts_la_SOURCES = xine_dts_decoder.c +xineplug_decode_dts_la_DEPENDENCIES = $(LIBDTS_DEPS) +xineplug_decode_dts_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(LIBDTS_LIBS) +xineplug_decode_dts_la_CFLAGS = $(AM_CFLAGS) $(LIBDTS_CFLAGS) + +xineplug_decode_mad_la_SOURCES = xine_mad_decoder.c +xineplug_decode_mad_la_DEPENDENCIES = $(LIBMAD_DEPS) +xineplug_decode_mad_la_LIBADD = $(XINE_LIB) $(LIBMAD_LIBS) +xineplug_decode_mad_la_CFLAGS = $(AM_CFLAGS) $(LIBMAD_CFLAGS) + +xineplug_decode_a52_la_SOURCES = xine_a52_decoder.c +xineplug_decode_a52_la_DEPENDENCIES = $(A52DEC_DEPS) +xineplug_decode_a52_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(A52DEC_LIBS) -lm +xineplug_decode_a52_la_CFLAGS = $(AM_CFLAGS) $(A52DEC_CFLAGS) + +xineplug_decode_faad_la_SOURCES = xine_faad_decoder.c +xineplug_decode_faad_la_DEPENDENCIES = $(FAAD_DEPS) +xineplug_decode_faad_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(FAAD_LIBS) -lm +xineplug_decode_faad_la_CFLAGS = $(FAAD_CFLAGS) diff --git a/src/audio_dec/fooaudio.c b/src/audio_dec/fooaudio.c new file mode 100644 index 000000000..b0ef63454 --- /dev/null +++ b/src/audio_dec/fooaudio.c @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2000-2001 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * fooaudio.c: This is a reference audio decoder for the xine multimedia + * player. It really works too! It will output a continuous sine wave in + * place of the data it should actually send. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +/* math.h required for fooaudio sine wave generation */ +#include + +#define AUDIOBUFSIZE 128*1024 + +typedef struct { + audio_decoder_class_t decoder_class; +} fooaudio_class_t; + +typedef struct fooaudio_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + int sample_rate; /* audio sample rate */ + int bits_per_sample; /* bits/sample, usually 8 or 16 */ + int channels; /* 1 or 2, usually */ + + int output_open; /* flag to indicate audio is ready */ + + unsigned char *buf; /* data accumulation buffer */ + int bufsize; /* maximum size of buf */ + int size; /* size of accumulated data in buf */ + + /* fooaudio-specific variables */ + int64_t last_pts; + unsigned int iteration; + +} fooaudio_decoder_t; + +/************************************************************************** + * fooaudio specific decode functions + *************************************************************************/ + +/************************************************************************** + * xine audio plugin functions + *************************************************************************/ + +static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; + audio_buffer_t *audio_buffer; + int i; + int64_t samples_to_generate; + int samples_to_send; + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { + + /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize + * the decoder. The buffer element type has 4 decoder_info fields, + * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field + * 3 is the number of channels. */ + this->sample_rate = buf->decoder_info[1]; + this->bits_per_sample = buf->decoder_info[2]; + this->channels = buf->decoder_info[3]; + + /* initialize the data accumulation buffer */ + this->buf = xine_xmalloc(AUDIOBUFSIZE); + this->bufsize = AUDIOBUFSIZE; + this->size = 0; + + /* take this opportunity to initialize stream/meta information */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "fooaudio"); + + /* perform any other required initialization */ + this->last_pts = -1; + this->iteration = 0; + + return; + } + + /* if the audio output is not open yet, open the audio output */ +#warning: Audio output is hardcoded to mono 16-bit PCM + if (!this->output_open) { + this->output_open = (this->stream->audio_out->open) ( + this->stream->audio_out, + this->stream, +/* this->bits_per_sample, */ + 16, + this->sample_rate, +/* _x_ao_channels2mode(this->channels));*/ + AO_CAP_MODE_MONO); + } + + /* if the audio still isn't open, do not go any further with the decode */ + if (!this->output_open) + return; + + /* accumulate the data passed through the buffer element type; increase + * the accumulator buffer size as necessary */ + if( this->size + buf->size > this->bufsize ) { + this->bufsize = this->size + 2 * buf->size; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "fooaudio: increasing source buffer to %d to avoid overflow.\n", this->bufsize); + this->buf = realloc( this->buf, this->bufsize ); + } + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + /* When a buffer element type has the BUF_FLAG_FRAME_END flag set, it is + * time to decode the data in the buffer. */ + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + /* This is where the real meat of the audio decoder is implemented. + * The general strategy is to decode the data in the accumulation buffer + * into raw PCM data and then dispatch the PCM to the engine in smaller + * buffers. What follows in the inside of this scope is the meat of + * this particular audio decoder. */ + + /* Operation of the fooaudio decoder: + * This decoder generates a continuous sine pattern based on the pts + * values sent by the xine engine. Two pts values are needed to know + * how long to make the audio. Thus, If this is the first frame or + * a seek has occurred (indicated by this->last_pts = -1), + * log the pts but do not create any audio. + * + * When a valid pts delta is generated, create n audio samples, where + * n is given as: + * + * n pts delta + * ----------- = --------- => n = (pts delta * sample rate) / 90000 + * sample rate 90000 + * + */ + + if (this->last_pts != -1) { + + /* no real reason to set this variable to 0 first; I just wanted the + * novelty of using all 4 basic arithmetic ops in a row (+ - * /) */ + samples_to_generate = 0; + samples_to_generate += buf->pts; + samples_to_generate -= this->last_pts; + samples_to_generate *= this->sample_rate; + samples_to_generate /= 90000; + + /* save the pts now since it will likely be trashed later */ + this->last_pts = buf->pts; + + while (samples_to_generate) { + + /* get an audio buffer */ + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + if (audio_buffer->mem_size == 0) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "fooaudio: Help! Allocated audio buffer with nothing in it!\n"); + return; + } + + /* samples_to_generate is a sample count; mem_size is a byte count */ + if (samples_to_generate > audio_buffer->mem_size / 2) + samples_to_send = audio_buffer->mem_size / 2; + else + samples_to_send = samples_to_generate; + samples_to_generate -= samples_to_send; + +#define WAVE_HZ 300 + /* fill up the samples in the buffer */ + for (i = 0; i < samples_to_send; i++) + audio_buffer->mem[i] = + (short)(sin(2 * M_PI * this->iteration++ / WAVE_HZ) * 32767); + + /* final prep for audio buffer dispatch */ + audio_buffer->num_frames = samples_to_send; + audio_buffer->vpts = buf->pts; + buf->pts = 0; /* only first buffer gets the real pts */ + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + + } + } else { + /* log the pts for the next time */ + this->last_pts = buf->pts; + } + + /* reset data accumulation buffer */ + this->size = 0; + } +} + +/* This function resets the state of the audio decoder. This usually + * entails resetting the data accumulation buffer. */ +static void fooaudio_reset (audio_decoder_t *this_gen) { + + fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; + + this->size = 0; + + /* this is specific to fooaudio */ + this->last_pts = -1; +} + +/* This function resets the last pts value of the audio decoder. */ +static void fooaudio_discontinuity (audio_decoder_t *this_gen) { + + fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; + + /* this is specific to fooaudio */ + this->last_pts = -1; +} + +/* This function closes the audio output and frees the private audio decoder + * structure. */ +static void fooaudio_dispose (audio_decoder_t *this_gen) { + + fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; + + /* close the audio output */ + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + + /* free anything that was allocated during operation */ + free(this->buf); + free(this); +} + +/* This function allocates, initializes, and returns a private audio + * decoder structure. */ +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + fooaudio_decoder_t *this ; + + this = (fooaudio_decoder_t *) xine_xmalloc (sizeof (fooaudio_decoder_t)); + + /* connect the member functions */ + this->audio_decoder.decode_data = fooaudio_decode_data; + this->audio_decoder.reset = fooaudio_reset; + this->audio_decoder.discontinuity = fooaudio_discontinuity; + this->audio_decoder.dispose = fooaudio_dispose; + + /* connect the stream */ + this->stream = stream; + + /* audio output is not open at the start */ + this->output_open = 0; + + /* initialize the basic audio parameters */ + this->channels = 0; + this->sample_rate = 0; + this->bits_per_sample = 0; + + /* initialize the data accumulation buffer */ + this->buf = NULL; + this->bufsize = 0; + this->size = 0; + + /* return the newly-initialized audio decoder */ + return &this->audio_decoder; +} + +/* This function frees the audio decoder class and any other memory that was + * allocated. */ +static void dispose_class (audio_decoder_class_t *this_gen) { + + fooaudio_class_t *this = (fooaudio_class_t *)this_gen; + + free (this); +} + +/* This function allocates a private audio decoder class and initializes + * the class's member functions. */ +static void *init_plugin (xine_t *xine, void *data) { + + fooaudio_class_t *this ; + + this = (fooaudio_class_t *) xine_malloc (sizeof (fooaudio_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "fooaudio"; + this->decoder_class.description = N_("fooaudio: reference xine audio decoder plugin"); + this->decoder_class.dispose = dispose_class; + + return this; +} + +/* This is a list of all of the internal xine audio buffer types that + * this decoder is able to handle. Check src/xine-engine/buffer.h for a + * list of valid buffer types (and add a new one if the one you need does + * not exist). Terminate the list with a 0. */ +static uint32_t audio_types[] = { + /* BUF_AUDIO_FOO, */ + 0 +}; + +/* This data structure combines the list of supported xine buffer types and + * the priority that the plugin should be given with respect to other + * plugins that handle the same buffer type. A plugin with priority (n+1) + * will be used instead of a plugin with priority (n). */ +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 5 /* priority */ +}; + +/* The plugin catalog entry. This is the only information that this plugin + * will export to the public. */ +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* { type, API version, "name", version, special_info, init_function }, */ + { PLUGIN_AUDIO_DECODER, 16, "fooaudio", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + diff --git a/src/audio_dec/gsm610.c b/src/audio_dec/gsm610.c new file mode 100644 index 000000000..8192aa7d8 --- /dev/null +++ b/src/audio_dec/gsm610.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * GSM 6.10 Audio Decoder + * This decoder is based on the GSM 6.10 codec library found at: + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * Additionally, here is an article regarding the software that appeared + * in Dr. Dobbs Journal: + * http://www.ddj.com/documents/s=1012/ddj9412b/9412b.htm + * + * This is the notice that comes with the software: + * -------------------------------------------------------------------- + * Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, + * Technische Universitaet Berlin + * + * Any use of this software is permitted provided that this notice is not + * removed and that neither the authors nor the Technische Universitaet Berlin + * are deemed to have made any representations as to the suitability of this + * software for any purpose nor are held responsible for any defects of + * this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + * + * As a matter of courtesy, the authors request to be informed about uses + * this software has found, about bugs in this software, and about any + * improvements that may be of general interest. + * + * Berlin, 28.11.1994 + * Jutta Degener + * Carsten Bormann + * -------------------------------------------------------------------- + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#include "private.h" +#include "gsm.h" + +#define AUDIOBUFSIZE 128*1024 + +#define GSM610_SAMPLE_SIZE 16 +#define GSM610_BLOCK_SIZE 160 + +typedef struct { + audio_decoder_class_t decoder_class; +} gsm610_class_t; + +typedef struct gsm610_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + unsigned int buf_type; + int output_open; + int sample_rate; + + unsigned char *buf; + int bufsize; + int size; + + gsm gsm_state; + +} gsm610_decoder_t; + +/************************************************************************** + * xine audio plugin functions + *************************************************************************/ + +static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen; + audio_buffer_t *audio_buffer; + int in_ptr; + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { + this->sample_rate = buf->decoder_info[1]; + + this->buf = xine_xmalloc(AUDIOBUFSIZE); + this->bufsize = AUDIOBUFSIZE; + this->size = 0; + + /* stream/meta info */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "GSM 6.10"); + + return; + } + + if (!this->output_open) { + + this->gsm_state = gsm_create(); + this->buf_type = buf->type; + + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, GSM610_SAMPLE_SIZE, this->sample_rate, AO_CAP_MODE_MONO); + } + + /* if the audio still isn't open, bail */ + if (!this->output_open) + return; + + if( this->size + buf->size > this->bufsize ) { + this->bufsize = this->size + 2 * buf->size; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "gsm610: increasing source buffer to %d to avoid overflow.\n", this->bufsize); + this->buf = realloc( this->buf, this->bufsize ); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ + int16_t decode_buffer[GSM610_BLOCK_SIZE]; + + /* handle the Microsoft variant of GSM data */ + if (this->buf_type == BUF_AUDIO_MSGSM) { + + this->gsm_state->wav_fmt = 1; + + /* the data should line up on a 65-byte boundary */ + if ((buf->size % 65) != 0) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "gsm610: received MS GSM block that does not line up\n"); + this->size = 0; + return; + } + + in_ptr = 0; + while (this->size) { + gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer); + if ((in_ptr % 65) == 0) { + in_ptr += 33; + this->size -= 33; + } else { + in_ptr += 32; + this->size -= 32; + } + + /* dispatch the decoded audio; assume that the audio buffer will + * always contain at least 160 samples */ + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + + xine_fast_memcpy(audio_buffer->mem, decode_buffer, + GSM610_BLOCK_SIZE * 2); + audio_buffer->num_frames = GSM610_BLOCK_SIZE; + + audio_buffer->vpts = buf->pts; + buf->pts = 0; /* only first buffer gets the real pts */ + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + } + } else { + + /* handle the other variant, which consists of 33-byte blocks */ + this->gsm_state->wav_fmt = 0; + + /* the data should line up on a 33-byte boundary */ + if ((buf->size % 33) != 0) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: received GSM block that does not line up\n"); + this->size = 0; + return; + } + + in_ptr = 0; + while (this->size) { + gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer); + in_ptr += 33; + this->size -= 33; + + /* dispatch the decoded audio; assume that the audio buffer will + * always contain at least 160 samples */ + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + + xine_fast_memcpy(audio_buffer->mem, decode_buffer, + GSM610_BLOCK_SIZE * 2); + audio_buffer->num_frames = GSM610_BLOCK_SIZE; + + audio_buffer->vpts = buf->pts; + buf->pts = 0; /* only first buffer gets the real pts */ + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + } + } + } +} + +static void gsm610_reset (audio_decoder_t *this_gen) { +} + +static void gsm610_discontinuity (audio_decoder_t *this_gen) { +} + +static void gsm610_dispose (audio_decoder_t *this_gen) { + + gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen; + + if (this->gsm_state) + gsm_destroy(this->gsm_state); + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + + if (this->buf) + free(this->buf); + + free (this_gen); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + gsm610_decoder_t *this ; + + this = (gsm610_decoder_t *) xine_xmalloc (sizeof (gsm610_decoder_t)); + + this->audio_decoder.decode_data = gsm610_decode_data; + this->audio_decoder.reset = gsm610_reset; + this->audio_decoder.discontinuity = gsm610_discontinuity; + this->audio_decoder.dispose = gsm610_dispose; + + this->output_open = 0; + this->sample_rate = 0; + this->stream = stream; + this->buf = NULL; + this->size = 0; + + return &this->audio_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + gsm610_class_t *this ; + + this = (gsm610_class_t *) xine_xmalloc (sizeof (gsm610_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "GSM 6.10"; + this->decoder_class.description = N_("GSM 6.10 audio decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_MSGSM, + BUF_AUDIO_GSM610, + 0 +}; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 9 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 16, "gsm610", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/audio_dec/xine_a52_decoder.c b/src/audio_dec/xine_a52_decoder.c new file mode 100644 index 000000000..e34504553 --- /dev/null +++ b/src/audio_dec/xine_a52_decoder.c @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * stuff needed to turn liba52 into a xine decoder plugin + */ + +#ifndef __sun +/* required for swab() */ +#define _XOPEN_SOURCE 500 +#endif +/* avoid compiler warnings */ +#define _BSD_SOURCE 1 + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "a52_decoder" +#define LOG_VERBOSE +/* +#define LOG +#define LOG_PTS +*/ + +#include +#include + +#ifdef HAVE_A52DEC_A52_H +# include +#else +# include "a52.h" +#endif + +#ifdef HAVE_A52DEC_A52_INTERNAL_H +# include +#else +# include "a52_internal.h" +#endif + +#include +#include + +#include "../../contrib/a52dec/crc.c" + +#undef DEBUG_A52 +#ifdef DEBUG_A52 +int a52file; +#endif + +typedef struct { + audio_decoder_class_t decoder_class; + config_values_t *config; + + float a52_level; + int disable_dynrng_compress; + int enable_surround_downmix; + +} a52dec_class_t; + +typedef struct a52dec_decoder_s { + audio_decoder_t audio_decoder; + + a52dec_class_t *class; + xine_stream_t *stream; + int64_t pts; + int64_t pts_list[5]; + int32_t pts_list_position; + + uint8_t frame_buffer[3840]; + uint8_t *frame_ptr; + int sync_state; + int frame_length, frame_todo; + uint16_t syncword; + + a52_state_t *a52_state; + int a52_flags; + int a52_bit_rate; + int a52_sample_rate; + int have_lfe; + + int a52_flags_map[11]; + int ao_flags_map[11]; + + int audio_caps; + int bypass_mode; + int output_sampling_rate; + int output_open; + int output_mode; + +} a52dec_decoder_t; + +struct frmsize_s +{ + uint16_t bit_rate; + uint16_t frm_size[3]; +}; + +static const struct frmsize_s frmsizecod_tbl[64] = +{ + { 32 ,{64 ,69 ,96 } }, + { 32 ,{64 ,70 ,96 } }, + { 40 ,{80 ,87 ,120 } }, + { 40 ,{80 ,88 ,120 } }, + { 48 ,{96 ,104 ,144 } }, + { 48 ,{96 ,105 ,144 } }, + { 56 ,{112 ,121 ,168 } }, + { 56 ,{112 ,122 ,168 } }, + { 64 ,{128 ,139 ,192 } }, + { 64 ,{128 ,140 ,192 } }, + { 80 ,{160 ,174 ,240 } }, + { 80 ,{160 ,175 ,240 } }, + { 96 ,{192 ,208 ,288 } }, + { 96 ,{192 ,209 ,288 } }, + { 112 ,{224 ,243 ,336 } }, + { 112 ,{224 ,244 ,336 } }, + { 128 ,{256 ,278 ,384 } }, + { 128 ,{256 ,279 ,384 } }, + { 160 ,{320 ,348 ,480 } }, + { 160 ,{320 ,349 ,480 } }, + { 192 ,{384 ,417 ,576 } }, + { 192 ,{384 ,418 ,576 } }, + { 224 ,{448 ,487 ,672 } }, + { 224 ,{448 ,488 ,672 } }, + { 256 ,{512 ,557 ,768 } }, + { 256 ,{512 ,558 ,768 } }, + { 320 ,{640 ,696 ,960 } }, + { 320 ,{640 ,697 ,960 } }, + { 384 ,{768 ,835 ,1152 } }, + { 384 ,{768 ,836 ,1152 } }, + { 448 ,{896 ,975 ,1344 } }, + { 448 ,{896 ,976 ,1344 } }, + { 512 ,{1024 ,1114 ,1536 } }, + { 512 ,{1024 ,1115 ,1536 } }, + { 576 ,{1152 ,1253 ,1728 } }, + { 576 ,{1152 ,1254 ,1728 } }, + { 640 ,{1280 ,1393 ,1920 } }, + { 640 ,{1280 ,1394 ,1920 } } +}; + +/* config callbacks */ +static void a52_level_change_cb(void *this_gen, xine_cfg_entry_t *entry); +static void dynrng_compress_change_cb(void *this_gen, xine_cfg_entry_t *entry); +static void surround_downmix_change_cb(void *this_gen, xine_cfg_entry_t *entry); + + +static void a52dec_reset (audio_decoder_t *this_gen) { + + a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; + + this->syncword = 0; + this->sync_state = 0; + this->pts = 0; + this->pts_list[0] = 0; + this->pts_list_position = 0; +} + +static void a52dec_discontinuity (audio_decoder_t *this_gen) { + + a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; + + this->pts = 0; + this->pts_list[0] = 0; + this->pts_list_position = 0; +} + +static inline int16_t blah (int32_t i) { + + if (i > 0x43c07fff) + return 32767; + else if (i < 0x43bf8000) + return -32768; + else + return i - 0x43c00000; +} + +static inline void float_to_int (float * _f, int16_t * s16, int num_channels) { + int i; + int32_t * f = (int32_t *) _f; /* XXX assumes IEEE float format */ + + for (i = 0; i < 256; i++) { + s16[num_channels*i] = blah (f[i]); + } +} + +static inline void mute_channel (int16_t * s16, int num_channels) { + int i; + + for (i = 0; i < 256; i++) { + s16[num_channels*i] = 0; + } +} + +static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts, int preview_mode) { + + int output_mode = AO_CAP_MODE_STEREO; + + /* + * do we want to decode this frame in software? + */ +#ifdef LOG_PTS + printf("a52dec:decode_frame:pts=%lld\n",pts); +#endif + if (!this->bypass_mode) { + + int a52_output_flags, i; + sample_t level = this->class->a52_level; + audio_buffer_t *buf; + int16_t *int_samples; + sample_t *samples = a52_samples(this->a52_state); + + /* + * oki, decode this frame in software + */ + + /* determine output mode */ + + a52_output_flags = this->a52_flags_map[this->a52_flags & A52_CHANNEL_MASK]; + + if (a52_frame (this->a52_state, + this->frame_buffer, + &a52_output_flags, + &level, 384)) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: a52_frame error\n"); + return; + } + + if (this->class->disable_dynrng_compress) + a52_dynrng (this->a52_state, NULL, NULL); + + this->have_lfe = a52_output_flags & A52_LFE; + if (this->have_lfe) + if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { + output_mode = AO_CAP_MODE_5_1CHANNEL; + } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { + output_mode = AO_CAP_MODE_4_1CHANNEL; + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: WHAT DO I DO!!!\n"); + output_mode = this->ao_flags_map[a52_output_flags]; + } + else + output_mode = this->ao_flags_map[a52_output_flags]; + /* + * (re-)open output device + */ + + if (!this->output_open + || (this->a52_sample_rate != this->output_sampling_rate) + || (output_mode != this->output_mode)) { + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, 16, + this->a52_sample_rate, + output_mode) ; + this->output_sampling_rate = this->a52_sample_rate; + this->output_mode = output_mode; + } + + + if (!this->output_open || preview_mode) + return; + + + /* + * decode a52 and convert/interleave samples + */ + + buf = this->stream->audio_out->get_buffer (this->stream->audio_out); + int_samples = buf->mem; + buf->num_frames = 256*6; + + for (i = 0; i < 6; i++) { + if (a52_block (this->a52_state)) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: a52_block error on audio channel %d\n", i); +#if 0 + for(n=0;n<2000;n++) { + printf("%02x ",this->frame_buffer[n]); + if ((n % 32) == 0) printf("\n"); + } + printf("\n"); +#endif + buf->num_frames = 0; + break; + } + + switch (output_mode) { + case AO_CAP_MODE_MONO: + float_to_int (&samples[0], int_samples+(i*256), 1); + break; + case AO_CAP_MODE_STEREO: + float_to_int (&samples[0*256], int_samples+(i*256*2), 2); + float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2); + break; + case AO_CAP_MODE_4CHANNEL: + float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */ + float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */ + float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */ + float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */ + break; + case AO_CAP_MODE_4_1CHANNEL: + float_to_int (&samples[0*256], int_samples+(i*256*6)+5, 6); /* LFE */ + float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ + float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ + float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ + float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ + mute_channel ( int_samples+(i*256*6)+4, 6); /* C */ + break; + case AO_CAP_MODE_5CHANNEL: + float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ + float_to_int (&samples[1*256], int_samples+(i*256*6)+4, 6); /* C */ + float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ + float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ + float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ + mute_channel ( int_samples+(i*256*6)+5, 6); /* LFE */ + break; + case AO_CAP_MODE_5_1CHANNEL: + float_to_int (&samples[0*256], int_samples+(i*256*6)+5, 6); /* lfe */ + float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ + float_to_int (&samples[2*256], int_samples+(i*256*6)+4, 6); /* C */ + float_to_int (&samples[3*256], int_samples+(i*256*6)+1, 6); /* R */ + float_to_int (&samples[4*256], int_samples+(i*256*6)+2, 6); /* RL */ + float_to_int (&samples[5*256], int_samples+(i*256*6)+3, 6); /* RR */ + break; + default: + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: help - unsupported mode %08x\n", output_mode); + } + } + + lprintf ("%d frames output\n", buf->num_frames); + + /* output decoded samples */ + + buf->vpts = pts; + + this->stream->audio_out->put_buffer (this->stream->audio_out, buf, this->stream); + + } else { + + /* + * loop through a52 data + */ + + if (!this->output_open) { + + int sample_rate, bit_rate, flags; + + a52_syncinfo (this->frame_buffer, &flags, &sample_rate, &bit_rate); + + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, 16, + sample_rate, + AO_CAP_MODE_A52) ; + this->output_mode = AO_CAP_MODE_A52; + } + + if (this->output_open && !preview_mode) { + /* SPDIF Passthrough + * Build SPDIF Header and encaps the A52 audio data in it. + */ + uint32_t syncword, crc1, fscod,frmsizecod,bsid,bsmod,frame_size; + uint8_t *data_out,*data_in; + audio_buffer_t *buf = this->stream->audio_out->get_buffer (this->stream->audio_out); + data_in=(uint8_t *) this->frame_buffer; + data_out=(uint8_t *) buf->mem; + syncword = data_in[0] | (data_in[1] << 8); + crc1 = data_in[2] | (data_in[3] << 8); + fscod = (data_in[4] >> 6) & 0x3; + frmsizecod = data_in[4] & 0x3f; + bsid = (data_in[5] >> 3) & 0x1f; + bsmod = data_in[5] & 0x7; /* bsmod, stream = 0 */ + frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] ; + + data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */ + data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */ + data_out[4] = 0x01; /* AC3 data */ + data_out[5] = bsmod; /* bsmod, stream = 0 */ + data_out[6] = (frame_size << 4) & 0xff; /* frame_size * 16 */ + data_out[7] = ((frame_size ) >> 4) & 0xff; + swab(data_in, &data_out[8], frame_size * 2 ); + + buf->num_frames = 1536; + buf->vpts = pts; + + this->stream->audio_out->put_buffer (this->stream->audio_out, buf, this->stream); + + } + } +} + +static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; + uint8_t *current = buf->content; + uint8_t *sync_start=current + 1; + uint8_t *end = buf->content + buf->size; + uint8_t byte; + int32_t n; + uint16_t crc16; + uint16_t crc16_result; + + lprintf ("decode data %d bytes of type %08x, pts=%"PRId64"\n", + buf->size, buf->type, buf->pts); + lprintf ("decode data decoder_info=%d, %d\n",buf->decoder_info[1],buf->decoder_info[2]); + + if (buf->decoder_flags & BUF_FLAG_HEADER) + return; + + /* swap byte pairs if this is RealAudio DNET data */ + if (buf->type == BUF_AUDIO_DNET) { + + lprintf ("byte-swapping dnet\n"); + + while (current != end) { + byte = *current++; + *(current - 1) = *current; + *current++ = byte; + } + + /* reset */ + current = buf->content; + end = buf->content + buf->size; + } + + /* A52 packs come from the DVD in blocks of about 2048 bytes. + * Only 1 PTS values can be assigned to each block. + * An A52 frame is about 1700 bytes long. + * So, a single A52 packs can contain 2 A52 frames (or the beginning of an A52 frame at least). + * If we have a PTS value, which A52 frame does it apply to? The A52 pack tells us that. + * So, the info about which A52 frame the PTS applies to is contained in decoder_info sent from the demuxer. + * + * The PTS value from the A52 pack (DVD sector) can only be applied at the start of an A52 frame. + * We call the start of an A52 frame a frame header. + * So, if a A52 pack has 2 "Number of frame headers" is means that the A52 pack contains 2 A52 frame headers. + * The "First access unit" then tells us which A52 frame the PTS value applies to. + * + * Take the following example: - + * PACK1: PTS = 10. Contains the entire A52 frame1, followed by the beginning of the frame2. PTS applies to frame1. + * PACK2: PTS = 1000, Contains the rest of frame2, and the whole of frame3. and the start of frame4. PTS applies to frame4. + * PACK3: PTS = 0 (none), Contains the rest of frame4. + * + * Output should be: - + * frame1, PTS=10 + * frame2, PTS=0 + * frame3, PTS=0 + * frame4, PTS=1000 + * + * So, we have to keep track of PTS values from previous A52 packs here, otherwise they get put on the wrong frame. + */ + + + /* FIXME: the code here does not match the explanation above */ + if (buf->pts) { + int32_t info; + info = buf->decoder_info[1]; + this->pts = buf->pts; + this->pts_list[this->pts_list_position]=buf->pts; + this->pts_list_position++; + if( this->pts_list_position > 3 ) + this->pts_list_position = 3; + if (info == 2) { + this->pts_list[this->pts_list_position]=0; + this->pts_list_position++; + if( this->pts_list_position > 3 ) + this->pts_list_position = 3; + } + } +#if 0 + for(n=0;n < buf->size;n++) { + if ((n % 32) == 0) printf("\n"); + printf("%x ", current[n]); + } + printf("\n"); +#endif + + lprintf ("processing...state %d\n", this->sync_state); + + while (current < end) { + switch (this->sync_state) { + case 0: /* Looking for sync header */ + this->syncword = (this->syncword << 8) | *current++; + if (this->syncword == 0x0b77) { + + this->frame_buffer[0] = 0x0b; + this->frame_buffer[1] = 0x77; + + this->sync_state = 1; + this->frame_ptr = this->frame_buffer+2; + } + break; + + case 1: /* Looking for enough bytes for sync_info. */ + sync_start = current - 1; + *this->frame_ptr++ = *current++; + if ((this->frame_ptr - this->frame_buffer) > 16) { + int a52_flags_old = this->a52_flags; + int a52_sample_rate_old = this->a52_sample_rate; + int a52_bit_rate_old = this->a52_bit_rate; + + this->frame_length = a52_syncinfo (this->frame_buffer, + &this->a52_flags, + &this->a52_sample_rate, + &this->a52_bit_rate); + + if (this->frame_length < 80) { /* Invalid a52 frame_length */ + this->syncword = 0; + current = sync_start; + this->sync_state = 0; + break; + } + + lprintf("Frame length = %d\n",this->frame_length); + + this->frame_todo = this->frame_length - 17; + this->sync_state = 2; + if (!_x_meta_info_get(this->stream, XINE_META_INFO_AUDIOCODEC) || + a52_flags_old != this->a52_flags || + a52_sample_rate_old != this->a52_sample_rate || + a52_bit_rate_old != this->a52_bit_rate) { + + switch (this->a52_flags & A52_CHANNEL_MASK) { + case A52_3F2R: + if (this->a52_flags & A52_LFE) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 5.1"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 5.0"); + break; + case A52_3F1R: + case A52_2F2R: + if (this->a52_flags & A52_LFE) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 4.1"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 4.0"); + break; + case A52_2F1R: + case A52_3F: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 3.0"); + break; + case A52_STEREO: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 2.0 (stereo)"); + break; + case A52_DOLBY: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 2.0 (dolby)"); + break; + case A52_MONO: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 1.0"); + break; + default: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52"); + break; + } + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->a52_bit_rate); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->a52_sample_rate); + } + } + break; + + case 2: /* Filling frame_buffer with sync_info bytes */ + *this->frame_ptr++ = *current++; + this->frame_todo--; + if (this->frame_todo < 1) { + this->sync_state = 3; + } else break; + + case 3: /* Ready for decode */ + crc16 = (uint16_t) ((this->frame_buffer[2] << 8) | this->frame_buffer[3]) ; + crc16_result = crc16_block(&this->frame_buffer[2], this->frame_length - 2) ; /* frame_length */ + if (crc16_result != 0) { /* CRC16 failed */ + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52:a52 frame failed crc16 checksum.\n"); + current = sync_start; + this->pts = 0; + this->syncword = 0; + this->sync_state = 0; + break; + } +#if 0 + a52dec_decode_frame (this, this->pts_list[0], buf->decoder_flags & BUF_FLAG_PREVIEW); +#else + a52dec_decode_frame (this, this->pts, buf->decoder_flags & BUF_FLAG_PREVIEW); +#endif + for(n=0;n<4;n++) { + this->pts_list[n] = this->pts_list[n+1]; + } + this->pts_list_position--; + if( this->pts_list_position < 0 ) + this->pts_list_position = 0; +#if 0 + printf("liba52: pts_list = %lld, %lld, %lld\n", + this->pts_list[0], + this->pts_list[1], + this->pts_list[2]); +#endif + case 4: /* Clear up ready for next frame */ + this->pts = 0; + this->syncword = 0; + this->sync_state = 0; + break; + default: /* No come here */ + break; + } + } + +#ifdef DEBUG_A52 + write (a52file, this->frame_buffer, this->frame_length); +#endif +} + +static void a52dec_dispose (audio_decoder_t *this_gen) { + + a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + this->output_open = 0; + + a52_free(this->a52_state); + this->a52_state = NULL; + +#ifdef DEBUG_A52 + close (a52file); +#endif + free (this_gen); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + a52dec_decoder_t *this ; + + lprintf ("open_plugin called\n"); + + this = (a52dec_decoder_t *) xine_xmalloc (sizeof (a52dec_decoder_t)); + + this->audio_decoder.decode_data = a52dec_decode_data; + this->audio_decoder.reset = a52dec_reset; + this->audio_decoder.discontinuity = a52dec_discontinuity; + this->audio_decoder.dispose = a52dec_dispose; + this->stream = stream; + this->class = (a52dec_class_t *) class_gen; + + /* int i; */ + + this->audio_caps = stream->audio_out->get_capabilities(stream->audio_out); + this->syncword = 0; + this->sync_state = 0; + this->output_open = 0; + this->pts = 0; + this->pts_list[0] = 0; + this->pts_list_position = 0; + + if( !this->a52_state ) + this->a52_state = a52_init (xine_mm_accel()); + + /* + * find out if this driver supports a52 output + * or, if not, how many channels we've got + */ + + if (this->audio_caps & AO_CAP_MODE_A52) + this->bypass_mode = 1; + else { + this->bypass_mode = 0; + + this->a52_flags_map[A52_MONO] = A52_MONO; + this->a52_flags_map[A52_STEREO] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + this->a52_flags_map[A52_3F] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + this->a52_flags_map[A52_2F1R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + this->a52_flags_map[A52_3F1R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + this->a52_flags_map[A52_2F2R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + this->a52_flags_map[A52_3F2R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + this->a52_flags_map[A52_DOLBY] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); + + this->ao_flags_map[A52_MONO] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_STEREO] = AO_CAP_MODE_STEREO; + this->ao_flags_map[A52_3F] = AO_CAP_MODE_STEREO; + this->ao_flags_map[A52_2F1R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[A52_3F1R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[A52_DOLBY] = AO_CAP_MODE_STEREO; + + /* find best mode */ + if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { + + this->a52_flags_map[A52_2F2R] = A52_2F2R; + this->a52_flags_map[A52_3F2R] = A52_3F2R | A52_LFE; + this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { + + this->a52_flags_map[A52_2F2R] = A52_2F2R; + this->a52_flags_map[A52_3F2R] = A52_3F2R; + this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { + + this->a52_flags_map[A52_2F2R] = A52_2F2R; + this->a52_flags_map[A52_3F2R] = A52_2F2R | A52_LFE; + this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_4CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) { + + this->a52_flags_map[A52_2F2R] = A52_2F2R; + this->a52_flags_map[A52_3F2R] = A52_2F2R; + + this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_4CHANNEL; + + /* else if (this->audio_caps & AO_CAP_MODE_STEREO) + defaults are ok */ + } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("HELP! a mono-only audio driver?!\n")); + + this->a52_flags_map[A52_MONO] = A52_MONO; + this->a52_flags_map[A52_STEREO] = A52_MONO; + this->a52_flags_map[A52_3F] = A52_MONO; + this->a52_flags_map[A52_2F1R] = A52_MONO; + this->a52_flags_map[A52_3F1R] = A52_MONO; + this->a52_flags_map[A52_2F2R] = A52_MONO; + this->a52_flags_map[A52_3F2R] = A52_MONO; + this->a52_flags_map[A52_DOLBY] = A52_MONO; + + this->ao_flags_map[A52_MONO] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_STEREO] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_3F] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_2F1R] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_3F1R] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_MONO; + this->ao_flags_map[A52_DOLBY] = AO_CAP_MODE_MONO; + } + } + + /* + for (i = 0; i<8; i++) + this->a52_flags_map[i] |= A52_ADJUST_LEVEL; + */ +#ifdef DEBUG_A52 + a52file = open ("test.a52", O_CREAT | O_WRONLY | O_TRUNC, 0644); +#endif + return &this->audio_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + a52dec_class_t *this; + config_values_t *cfg; + + this = (a52dec_class_t *) xine_xmalloc (sizeof (a52dec_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "a/52dec"; + this->decoder_class.description = N_("liba52 based a52 audio decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + cfg = this->config = xine->config; + + this->a52_level = (float) cfg->register_range (cfg, "audio.a52.level", 100, + 0, 200, + _("A/52 volume"), + _("With A/52 audio, you can modify the volume " + "at the decoder level. This has the advantage " + "of the audio being already decoded for the " + "specified volume, so later operations like " + "channel downmixing will work on an audio stream " + "of the given volume."), + 10, a52_level_change_cb, this) / 100.0; + this->disable_dynrng_compress = !cfg->register_bool (cfg, "audio.a52.dynamic_range", 0, + _("use A/52 dynamic range compression"), + _("Dynamic range compression limits the dynamic " + "range of the audio. This means making the loud " + "sounds softer, and the soft sounds louder, so you can " + "more easily listen to the audio in a noisy " + "environment without disturbing anyone."), + 0, dynrng_compress_change_cb, this); + this->enable_surround_downmix = cfg->register_bool (cfg, "audio.a52.surround_downmix", 0, + _("downmix audio to 2 channel surround stereo"), + _("When you want to listen to multichannel surround " + "sound, but you have only two speakers or a " + "surround decoder or amplifier which does some " + "sort of matrix surround decoding like prologic, " + "you should enable this option so that the " + "additional channels are mixed into the stereo " + "signal."), + 0, surround_downmix_change_cb, this); + lprintf ("init_plugin called\n"); + return this; +} + +static void a52_level_change_cb(void *this_gen, xine_cfg_entry_t *entry) +{ + ((a52dec_class_t *)this_gen)->a52_level = entry->num_value / 100.0; +} + +static void dynrng_compress_change_cb(void *this_gen, xine_cfg_entry_t *entry) +{ + ((a52dec_class_t *)this_gen)->disable_dynrng_compress = !entry->num_value; +} + +static void surround_downmix_change_cb(void *this_gen, xine_cfg_entry_t *entry) +{ + ((a52dec_class_t *)this_gen)->enable_surround_downmix = entry->num_value; +} + + +static uint32_t audio_types[] = { + BUF_AUDIO_A52, + BUF_AUDIO_DNET, + 0 + }; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 5 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "a/52", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/audio_dec/xine_dts_decoder.c b/src/audio_dec/xine_dts_decoder.c new file mode 100644 index 000000000..9d2fc5e93 --- /dev/null +++ b/src/audio_dec/xine_dts_decoder.c @@ -0,0 +1,578 @@ +/* + * Copyright (C) 2000-2007 the xine project + * + * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +/** + * @file + * @brief DTS decoder for xine + * + * @author Joachim Koenig (2001-09-04) + * @author James Courtier-Dutton (2001-12-09) + */ + +#ifndef __sun +/* required for swab() */ +#define _XOPEN_SOURCE 500 +#endif +/* avoid compiler warnings */ +#define _BSD_SOURCE 1 + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "libdts" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include + +#include "bswap.h" + +#include + +#define MAX_AC5_FRAME 4096 + +typedef struct { + audio_decoder_class_t decoder_class; +} dts_class_t; + +typedef struct { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + audio_decoder_class_t *class; + + dts_state_t *dts_state; + int64_t pts; + + int audio_caps; + int sync_state; + int ac5_length, ac5_pcm_length, frame_todo; + uint32_t syncdword; + uint8_t frame_buffer[MAX_AC5_FRAME]; + uint8_t *frame_ptr; + + int output_open; + + int bypass_mode; + int dts_flags; + int dts_sample_rate; + int dts_bit_rate; + int dts_flags_map[11]; /* Convert from stream dts_flags to the dts_flags we want from the dts downmixer */ + int ao_flags_map[11]; /* Convert from the xine AO_CAP's to dts_flags. */ + int have_lfe; + + +} dts_decoder_t; + +static void dts_reset (audio_decoder_t *const this_gen) { +} + +static void dts_discontinuity (audio_decoder_t *const this_gen) { +} + +/** + * @brief Convert a array of floating point samples into 16-bit signed integer samples + * @param f Floating point samples array (origin) + * @param s16 16-bit signed integer samples array (destination) + * @param num_channels Number of channels present in the stream + * + * @todo This same work is being done in many decoders to adapt the output of + * the decoder to what the audio output can actually use, this should be + * done by the audio_output loop, not by the decoders. + * @note This is subtly different from the function with the same name in xine_musepack_decoder.c + */ +static inline void float_to_int (const float *const _f, int16_t *const s16, const int num_channels) { + const int endidx = 256 * num_channels; + int i, j; + + for (i = 0, j = 0; j < endidx; i++, j += num_channels) { + const float f = _f[i] * 32767; + if (f > INT16_MAX) + s16[j] = INT16_MAX; + else if (f < INT16_MIN) + s16[j] = INT16_MIN; + else + s16[j] = f; + /* printf("samples[%d] = %f, %d\n", i, _f[i], s16[num_channels*i]); */ + } +} + +static inline void mute_channel (int16_t *const s16, const int num_channels) { + const int endidx = 256 * num_channels; + int i; + + for (i = 0; i < endidx; i += num_channels) + s16[i] = 0; +} + +static void dts_decode_frame (dts_decoder_t *this, const int64_t pts, const int preview_mode) { + + audio_buffer_t *audio_buffer; + uint32_t ac5_spdif_type=0; + int output_mode = AO_CAP_MODE_STEREO; + uint8_t *data_out; + uint8_t *const data_in = this->frame_buffer; + + lprintf("decode_frame\n"); + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + audio_buffer->vpts = pts; + + if(this->bypass_mode) { + /* SPDIF digital output */ + if (!this->output_open) { + this->output_open = ((this->stream->audio_out->open) (this->stream->audio_out, this->stream, + 16, this->dts_sample_rate, + AO_CAP_MODE_AC5)); + } + + if (!this->output_open) + return; + + data_out=(uint8_t *) audio_buffer->mem; + if (this->ac5_length > 8191) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: ac5_length too long\n"); + this->ac5_pcm_length = 0; + } + + switch (this->ac5_pcm_length) { + case 512: + ac5_spdif_type = 0x0b; /* DTS-1 (512-sample bursts) */ + break; + case 1024: + ac5_spdif_type = 0x0c; /* DTS-1 (1024-sample bursts) */ + break; + case 2048: + ac5_spdif_type = 0x0d; /* DTS-1 (2048-sample bursts) */ + break; + default: + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libdts: DTS %i-sample bursts not supported\n", this->ac5_pcm_length); + return; + } + +#ifdef LOG_DEBUG + { + int i; + printf("libdts: DTS frame type=%d\n",data_in[4] >> 7); + printf("libdts: DTS deficit frame count=%d\n",(data_in[4] & 0x7f) >> 2); + printf("libdts: DTS AC5 PCM samples=%d\n",ac5_pcm_samples); + printf("libdts: DTS AC5 length=%d\n",this->ac5_length); + printf("libdts: DTS AC5 bitrate=%d\n",((data_in[8] & 0x03) << 4) | (data_in[8] >> 4)); + printf("libdts: DTS AC5 spdif type=%d\n", ac5_spdif_type); + + printf("libdts: "); + for(i=2000;i<2048;i++) { + printf("%02x ",data_in[i]); + } + printf("\n"); + } +#endif + + lprintf("length=%d pts=%"PRId64"\n",this->ac5_pcm_length,audio_buffer->vpts); + + audio_buffer->num_frames = this->ac5_pcm_length; + + data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */ + data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */ + data_out[4] = ac5_spdif_type; /* DTS data */ + data_out[5] = 0; /* Unknown */ + data_out[6] = (this->ac5_length << 3) & 0xff; /* ac5_length * 8 */ + data_out[7] = ((this->ac5_length ) >> 5) & 0xff; + + if( this->ac5_pcm_length ) { + if( this->ac5_pcm_length % 2) { + swab(data_in, &data_out[8], this->ac5_length ); + } else { + swab(data_in, &data_out[8], this->ac5_length + 1); + } + } + } else { + /* Software decode */ + int i, dts_output_flags; + int16_t *const int_samples = audio_buffer->mem; + int number_of_dts_blocks; + + level_t level = 1.0; + sample_t *samples; + + dts_output_flags = this->dts_flags_map[this->dts_flags & DTS_CHANNEL_MASK]; + + if(dts_frame(this->dts_state, data_in, &dts_output_flags, &level, 0)) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: dts_frame error\n"); + return; + } + + this->have_lfe = dts_output_flags & DTS_LFE; + if (this->have_lfe) + if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { + output_mode = AO_CAP_MODE_5_1CHANNEL; + } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { + output_mode = AO_CAP_MODE_4_1CHANNEL; + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: WHAT DO I DO!!!\n"); + output_mode = this->ao_flags_map[dts_output_flags & DTS_CHANNEL_MASK]; + } + else + output_mode = this->ao_flags_map[dts_output_flags & DTS_CHANNEL_MASK]; + + if (!this->output_open) { + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, + 16, this->dts_sample_rate, + output_mode); + } + + if (!this->output_open) + return; + number_of_dts_blocks = dts_blocks_num (this->dts_state); + audio_buffer->num_frames = 256*number_of_dts_blocks; + for(i = 0; i < number_of_dts_blocks; i++) { + if(dts_block(this->dts_state)) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libdts: dts_block error on audio channel %d\n", i); + audio_buffer->num_frames = 0; + break; + } + + samples = dts_samples(this->dts_state); + switch (output_mode) { + case AO_CAP_MODE_MONO: + float_to_int (&samples[0], int_samples+(i*256), 1); + break; + case AO_CAP_MODE_STEREO: + /* Tested, working. */ + float_to_int (&samples[0*256], int_samples+(i*256*2), 2); /* L */ + float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2); /* R */ + break; + case AO_CAP_MODE_4CHANNEL: + /* Tested, working */ + float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */ + float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */ + float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */ + float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */ + break; + case AO_CAP_MODE_4_1CHANNEL: + /* Tested, working */ + float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ + float_to_int (&samples[1*256], int_samples+(i*256*6)+1, 6); /* R */ + float_to_int (&samples[2*256], int_samples+(i*256*6)+2, 6); /* RL */ + float_to_int (&samples[3*256], int_samples+(i*256*6)+3, 6); /* RR */ + float_to_int (&samples[4*256], int_samples+(i*256*6)+5, 6); /* LFE */ + mute_channel ( int_samples+(i*256*6)+4, 6); /* C */ + break; + case AO_CAP_MODE_5CHANNEL: + /* Tested, working */ + float_to_int (&samples[0*256], int_samples+(i*256*6)+4, 6); /* C */ + float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ + float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ + float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ + float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ + mute_channel ( int_samples+(i*256*6)+5, 6); /* LFE */ + break; + case AO_CAP_MODE_5_1CHANNEL: + float_to_int (&samples[0*256], int_samples+(i*256*6)+4, 6); /* C */ + float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ + float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ + float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ + float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ + float_to_int (&samples[5*256], int_samples+(i*256*6)+5, 6); /* LFE */ /* Not working yet */ + break; + default: + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: help - unsupported mode %08x\n", output_mode); + } + } + } + + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + + +} + +static void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + dts_decoder_t *const this = (dts_decoder_t *) this_gen; + uint8_t *current = (uint8_t *)buf->content; + uint8_t *sync_start=current + 1; + uint8_t *const end = buf->content + buf->size; + + lprintf("decode_data\n"); + + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + if (buf->decoder_flags & BUF_FLAG_STDHEADER) + return; + + lprintf ("processing...state %d\n", this->sync_state); + + while (current < end) { + switch (this->sync_state) { + case 0: /* Looking for sync header */ + this->syncdword = (this->syncdword << 8) | *current++; +/* + if ((this->syncdword == 0xff1f00e8) || + (this->syncdword == 0x1fffe800) || + (this->syncdword == 0xfe7f0180) || + (this->syncdword == 0x7ffe8001) ) { +*/ + + if ((this->syncdword == 0x7ffe8001) || (this->syncdword == 0xff1f00e8)) { + const uint32_t be_syncdword = be2me_32(this->syncdword); + + lprintf ("sync found: syncdword=0x%x\n", this->syncdword); + + memcpy(this->frame_buffer, &be_syncdword, sizeof(be_syncdword)); + + this->sync_state = 1; + this->frame_ptr = this->frame_buffer+4; + this->pts = buf->pts; + } + break; + + case 1: /* Looking for enough bytes for sync_info. */ + sync_start = current - 1; + *this->frame_ptr++ = *current++; + if ((this->frame_ptr - this->frame_buffer) > 19) { + const int old_dts_flags = this->dts_flags; + const int old_dts_sample_rate = this->dts_sample_rate; + const int old_dts_bit_rate = this->dts_bit_rate; + + this->ac5_length = dts_syncinfo (this->dts_state, this->frame_buffer, + &this->dts_flags, + &this->dts_sample_rate, + &this->dts_bit_rate, &(this->ac5_pcm_length)); + lprintf("ac5_length=%d\n",this->ac5_length); + lprintf("dts_sample_rate=%d\n",this->dts_sample_rate); + + if ( (this->ac5_length < 80) || (this->ac5_length > MAX_AC5_FRAME) ) { /* Invalid dts ac5_pcm_length */ + this->syncdword = 0; + current = sync_start; + this->sync_state = 0; + break; + } + + lprintf("Frame length = %d\n",this->ac5_pcm_length); + + this->frame_todo = this->ac5_length - 20; + this->sync_state = 2; + if (!_x_meta_info_get(this->stream, XINE_META_INFO_AUDIOCODEC) || + old_dts_flags != this->dts_flags || + old_dts_sample_rate != this->dts_sample_rate || + old_dts_bit_rate != this->dts_bit_rate) { + + switch (this->dts_flags & DTS_CHANNEL_MASK) { + case DTS_3F2R: + if (this->dts_flags & DTS_LFE) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 5.1"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 5.0"); + break; + case DTS_3F1R: + case DTS_2F2R: + if (this->dts_flags & DTS_LFE) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 4.1"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 4.0"); + break; + case DTS_2F1R: + case DTS_3F: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 3.0"); + break; + case DTS_STEREO: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 2.0 (stereo)"); + break; + case DTS_MONO: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 1.0"); + break; + default: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS"); + break; + } + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->dts_bit_rate); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->dts_sample_rate); + } + } + break; + + case 2: /* Filling frame_buffer with sync_info bytes */ + *this->frame_ptr++ = *current++; + this->frame_todo--; + if (this->frame_todo < 1) { + this->sync_state = 3; + } else break; + + case 3: /* Ready for decode */ +#if 0 + dtsdec_decode_frame (this, this->pts_list[0], buf->decoder_flags & BUF_FLAG_PREVIEW); +#else + dts_decode_frame (this, this->pts, buf->decoder_flags & BUF_FLAG_PREVIEW); +#endif + case 4: /* Clear up ready for next frame */ + this->pts = 0; + this->syncdword = 0; + this->sync_state = 0; + break; + default: /* No come here */ + break; + } + } +} + +static void dts_dispose (audio_decoder_t *this_gen) { + dts_decoder_t *const this = (dts_decoder_t *) this_gen; + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + free (this); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + dts_decoder_t *this ; + + lprintf("open_plugin\n"); + + this = (dts_decoder_t *) xine_xmalloc (sizeof (dts_decoder_t)); + + this->audio_decoder.decode_data = dts_decode_data; + this->audio_decoder.reset = dts_reset; + this->audio_decoder.discontinuity = dts_discontinuity; + this->audio_decoder.dispose = dts_dispose; + + this->dts_state = dts_init(0); + this->audio_caps = stream->audio_out->get_capabilities(stream->audio_out); + if(this->audio_caps & AO_CAP_MODE_AC5) + this->bypass_mode = 1; + else { + this->bypass_mode = 0; + /* FIXME: Leave "DOLBY pro logic" downmix out for now. */ + this->dts_flags_map[DTS_MONO] = DTS_MONO; + this->dts_flags_map[DTS_STEREO] = DTS_STEREO; + this->dts_flags_map[DTS_3F] = DTS_STEREO; + this->dts_flags_map[DTS_2F1R] = DTS_STEREO; + this->dts_flags_map[DTS_3F1R] = DTS_STEREO; + this->dts_flags_map[DTS_2F2R] = DTS_STEREO; + this->dts_flags_map[DTS_3F2R] = DTS_STEREO; + + this->ao_flags_map[DTS_MONO] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_STEREO] = AO_CAP_MODE_STEREO; + this->ao_flags_map[DTS_3F] = AO_CAP_MODE_STEREO; + this->ao_flags_map[DTS_2F1R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[DTS_3F1R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_STEREO; + + /* find best mode */ + if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { + + this->dts_flags_map[DTS_2F2R] = DTS_2F2R; + this->dts_flags_map[DTS_3F2R] = DTS_3F2R | DTS_LFE; + this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { + + this->dts_flags_map[DTS_2F2R] = DTS_2F2R; + this->dts_flags_map[DTS_3F2R] = DTS_3F2R; + this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { + + this->dts_flags_map[DTS_2F2R] = DTS_2F2R; + this->dts_flags_map[DTS_3F2R] = DTS_2F2R | DTS_LFE; + this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_4CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) { + + this->dts_flags_map[DTS_2F2R] = DTS_2F2R; + this->dts_flags_map[DTS_3F2R] = DTS_2F2R; + + this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_4CHANNEL; + + /* else if (this->audio_caps & AO_CAP_MODE_STEREO) + defaults are ok */ + } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("HELP! a mono-only audio driver?!\n")); + + this->dts_flags_map[DTS_MONO] = DTS_MONO; + this->dts_flags_map[DTS_STEREO] = DTS_MONO; + this->dts_flags_map[DTS_3F] = DTS_MONO; + this->dts_flags_map[DTS_2F1R] = DTS_MONO; + this->dts_flags_map[DTS_3F1R] = DTS_MONO; + this->dts_flags_map[DTS_2F2R] = DTS_MONO; + this->dts_flags_map[DTS_3F2R] = DTS_MONO; + + this->ao_flags_map[DTS_MONO] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_STEREO] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_3F] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_2F1R] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_3F1R] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_MONO; + this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_MONO; + } + } + this->stream = stream; + this->class = class_gen; + this->output_open = 0; + + return &this->audio_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + dts_class_t *this ; + + lprintf("init_plugin\n"); + + this = (dts_class_t *) xine_xmalloc (sizeof (dts_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "DTS"; + this->decoder_class.description = N_("DTS passthru audio format decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_DTS, 0 + }; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 16, "dts", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/audio_dec/xine_faad_decoder.c b/src/audio_dec/xine_faad_decoder.c new file mode 100644 index 000000000..6b242005a --- /dev/null +++ b/src/audio_dec/xine_faad_decoder.c @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2000-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "libfaad" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include +#ifdef HAVE_NEAACDEC_H +#include +#else +#include "common.h" +#include "structs.h" +#include "decoder.h" +#include "syntax.h" +#endif + +#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */ + +typedef struct { + audio_decoder_class_t decoder_class; +} faad_class_t; + +typedef struct faad_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + /* faad2 stuff */ + NeAACDecHandle faac_dec; + NeAACDecConfigurationPtr faac_cfg; + NeAACDecFrameInfo faac_finfo; + int faac_failed; + + int raw_mode; + + unsigned char *buf; + int size; + int rec_audio_src_size; + int max_audio_src_size; + int pts; + + unsigned char *dec_config; + int dec_config_size; + + unsigned long rate; + int bits_per_sample; + unsigned char num_channels; + int sbr; + + int output_open; + + unsigned long total_time; + unsigned long total_data; +} faad_decoder_t; + + +static void faad_reset (audio_decoder_t *this_gen) { + + faad_decoder_t *this = (faad_decoder_t *) this_gen; + this->size = 0; +} + +static void faad_meta_info_set ( faad_decoder_t *this ) { + switch (this->num_channels) { + case 1: + if (this->faac_finfo.sbr == SBR_UPSAMPLED) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "HE-AAC 1.0 (libfaad)"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "AAC 1.0 (libfaad)"); + break; + case 2: + /* check if this is downmixed 5.1 */ + if (!this->faac_cfg || !this->faac_cfg->downMatrix) { + if (this->faac_finfo.sbr == SBR_UPSAMPLED) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "HE-AAC 2.0 (libfaad)"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "AAC 2.0 (libfaad)"); + break; + } + case 6: + if (this->faac_finfo.sbr == SBR_UPSAMPLED) + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "HE-AAC 5.1 (libfaad)"); + else + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "AAC 5.1 (libfaad)"); + break; + } +} + +static int faad_open_dec( faad_decoder_t *this ) { + int used; + + this->faac_dec = NeAACDecOpen(); + if( !this->faac_dec ) { + xprintf( this->stream->xine, XINE_VERBOSITY_LOG, + _("libfaad: libfaad NeAACDecOpen() failed.\n")); + this->faac_failed++; + } else { + if( this->dec_config ) { + used = NeAACDecInit2(this->faac_dec, this->dec_config, this->dec_config_size, + &this->rate, &this->num_channels); + + if( used < 0 ) { + xprintf( this->stream->xine, XINE_VERBOSITY_LOG, + _("libfaad: libfaad NeAACDecInit2 failed.\n")); + this->faac_failed++; + } else + lprintf( "NeAACDecInit2 returned rate=%"PRId32" channels=%d\n", + this->rate, this->num_channels ); + } else { + used = NeAACDecInit(this->faac_dec, this->buf, this->size, + &this->rate, &this->num_channels); + + if( used < 0 ) { + xprintf ( this->stream->xine, XINE_VERBOSITY_LOG, + _("libfaad: libfaad NeAACDecInit failed.\n")); + this->faac_failed++; + } else { + lprintf( "NeAACDecInit() returned rate=%"PRId32" channels=%d (used=%d)\n", + this->rate, this->num_channels, used); + + this->size -= used; + memmove( this->buf, &this->buf[used], this->size ); + } + } + } + + if( !this->bits_per_sample ) + this->bits_per_sample = 16; + + if( this->faac_failed ) { + if( this->faac_dec ) { + NeAACDecClose( this->faac_dec ); + this->faac_dec = NULL; + } + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + } else { + faad_meta_info_set(this); + } + + return this->faac_failed; +} + +static int faad_open_output( faad_decoder_t *this ) { + int ao_cap_mode; + + this->rec_audio_src_size = this->num_channels * FAAD_MIN_STREAMSIZE; + + switch( this->num_channels ) { + case 1: + ao_cap_mode=AO_CAP_MODE_MONO; + break; + case 6: + if(this->stream->audio_out->get_capabilities(this->stream->audio_out) & + AO_CAP_MODE_5_1CHANNEL) { + ao_cap_mode = AO_CAP_MODE_5_1CHANNEL; + break; + } else { + this->faac_cfg = NeAACDecGetCurrentConfiguration(this->faac_dec); + this->faac_cfg->downMatrix = 1; + NeAACDecSetConfiguration(this->faac_dec, this->faac_cfg); + this->num_channels = 2; + } + case 2: + ao_cap_mode=AO_CAP_MODE_STEREO; + break; + default: + return 0; + } + + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, + this->bits_per_sample, + this->rate, + ao_cap_mode) ; + return this->output_open; +} + +static void faad_decode_audio ( faad_decoder_t *this, int end_frame ) { + int used, decoded, outsize; + uint8_t *sample_buffer; + uint8_t *inbuf; + audio_buffer_t *audio_buffer; + int sample_size = this->size; + + if( !this->faac_dec ) + return; + + inbuf = this->buf; + while( (!this->raw_mode && end_frame && this->size >= 10) || + (this->raw_mode && this->size >= this->rec_audio_src_size) ) { + + sample_buffer = NeAACDecDecode(this->faac_dec, + &this->faac_finfo, inbuf, sample_size); + + if( !sample_buffer ) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libfaad: %s\n", NeAACDecGetErrorMessage(this->faac_finfo.error)); + used = 1; + } else { + used = this->faac_finfo.bytesconsumed; + + /* raw AAC parameters might only be known after decoding the first frame */ + if( !this->dec_config && + (this->num_channels != this->faac_finfo.channels || + this->rate != this->faac_finfo.samplerate) ) { + + this->num_channels = this->faac_finfo.channels; + this->rate = this->faac_finfo.samplerate; + + lprintf("NeAACDecDecode() returned rate=%"PRId32" channels=%d used=%d\n", + this->rate, this->num_channels, used); + + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + faad_open_output( this ); + + faad_meta_info_set( this ); + } + + /* faad doesn't tell us about sbr until after the first frame */ + if (this->sbr != this->faac_finfo.sbr) { + this->sbr = this->faac_finfo.sbr; + faad_meta_info_set( this ); + } + + /* estimate bitrate */ + this->total_time += (1000*this->faac_finfo.samples/(this->rate*this->num_channels)); + this->total_data += 8*used; + + if ((this->total_time > LONG_MAX) || (this->total_data > LONG_MAX)) { + this->total_time >>= 2; + this->total_data >>= 2; + } + + if (this->total_time) + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, + 1000*(this->total_data/this->total_time)); + + decoded = this->faac_finfo.samples * 2; /* 1 sample = 2 bytes */ + + lprintf("decoded %d/%d output %ld\n", + used, this->size, this->faac_finfo.samples ); + + while( decoded ) { + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + + if( decoded < audio_buffer->mem_size ) + outsize = decoded; + else + outsize = audio_buffer->mem_size; + + xine_fast_memcpy( audio_buffer->mem, sample_buffer, outsize ); + + audio_buffer->num_frames = outsize / (this->num_channels*2); + audio_buffer->vpts = this->pts; + + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + + this->pts = 0; + decoded -= outsize; + sample_buffer += outsize; + } + } + + if(used >= this->size){ + this->size = 0; + } else { + this->size -= used; + inbuf += used; + } + + if( !this->raw_mode ) + this->size = 0; + } + + if( this->size ) + memmove( this->buf, inbuf, this->size); + +} + +static void faad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + faad_decoder_t *this = (faad_decoder_t *) this_gen; + + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + /* store config information from ESDS mp4/qt atom */ + if( !this->faac_dec && (buf->decoder_flags & BUF_FLAG_SPECIAL) && + buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG ) { + + this->dec_config = xine_xmalloc(buf->decoder_info[2]); + this->dec_config_size = buf->decoder_info[2]; + memcpy(this->dec_config, buf->decoder_info_ptr[2], buf->decoder_info[2]); + + if( faad_open_dec(this) ) + return; + + this->raw_mode = 0; + } + + /* get audio parameters from file header + (may be overwritten by libfaad returned parameters) */ + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { + this->rate=buf->decoder_info[1]; + this->bits_per_sample=buf->decoder_info[2] ; + this->num_channels=buf->decoder_info[3] ; + + if( buf->size > sizeof(xine_waveformatex) ) { + xine_waveformatex *wavex = (xine_waveformatex *) buf->content; + + if( wavex->cbSize > 0 ) { + this->dec_config = xine_xmalloc(wavex->cbSize); + this->dec_config_size = wavex->cbSize; + memcpy(this->dec_config, buf->content + sizeof(xine_waveformatex), + wavex->cbSize); + + if( faad_open_dec(this) ) + return; + + this->raw_mode = 0; + } + } + } else { + + lprintf ("decoding %d data bytes...\n", buf->size); + + if( (int)buf->size <= 0 || this->faac_failed ) + return; + + if( !this->size ) + this->pts = buf->pts; + + if( this->size + buf->size > this->max_audio_src_size ) { + this->max_audio_src_size = this->size + 2 * buf->size; + this->buf = realloc( this->buf, this->max_audio_src_size ); + } + + memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + if( !this->faac_dec && faad_open_dec(this) ) + return; + + /* open audio device as needed */ + if (!this->output_open) { + faad_open_output( this ); + } + + faad_decode_audio(this, buf->decoder_flags & BUF_FLAG_FRAME_END ); + } +} + +static void faad_discontinuity (audio_decoder_t *this_gen) { +} + +static void faad_dispose (audio_decoder_t *this_gen) { + + faad_decoder_t *this = (faad_decoder_t *) this_gen; + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + + if( this->buf ) + free(this->buf); + this->buf = NULL; + this->size = 0; + this->max_audio_src_size = 0; + + if( this->dec_config ) + free(this->dec_config); + this->dec_config = NULL; + this->dec_config_size = 0; + + if( this->faac_dec ) + NeAACDecClose(this->faac_dec); + this->faac_dec = NULL; + this->faac_failed = 0; + + free (this); +} + + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + faad_decoder_t *this ; + + this = (faad_decoder_t *) xine_xmalloc (sizeof (faad_decoder_t)); + + this->audio_decoder.decode_data = faad_decode_data; + this->audio_decoder.reset = faad_reset; + this->audio_decoder.discontinuity = faad_discontinuity; + this->audio_decoder.dispose = faad_dispose; + + this->stream = stream; + this->output_open = 0; + this->raw_mode = 1; + this->faac_dec = NULL; + this->faac_failed = 0; + this->buf = NULL; + this->size = 0; + this->max_audio_src_size = 0; + this->dec_config = NULL; + this->dec_config_size = 0; + this->total_time = 0; + this->total_data = 0; + + this->rate = 0; + + return &this->audio_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + faad_class_t *this ; + + this = (faad_class_t *) xine_xmalloc (sizeof (faad_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "FAAD"; + this->decoder_class.description = N_("Freeware Advanced Audio Decoder"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_AAC, 0 + }; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 16, "faad", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/audio_dec/xine_lpcm_decoder.c b/src/audio_dec/xine_lpcm_decoder.c new file mode 100644 index 000000000..51d2e3137 --- /dev/null +++ b/src/audio_dec/xine_lpcm_decoder.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +/** + * @file + * @author James Courtier-Dutton + * + * @date 2001-08-31 Added LPCM rate sensing + */ + +#ifndef __sun +#define _XOPEN_SOURCE 500 +#endif +/* avoid compiler warnings */ +#define _BSD_SOURCE 1 + +#include +#include +#include +#include +#include +#include +#include /* ntohs */ + +#include +#include +#include + +#ifdef WIN32 +#include +/*#include */ /* htons */ +#endif + +typedef struct { + audio_decoder_class_t decoder_class; +} lpcm_class_t; + +typedef struct lpcm_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + uint32_t rate; + uint32_t bits_per_sample; + uint32_t number_of_channels; + uint32_t ao_cap_mode; + + int output_open; + int cpu_be; /**< TRUE, if we're a Big endian CPU */ +} lpcm_decoder_t; + +static void lpcm_reset (audio_decoder_t *this_gen) { + + /* lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; */ + +} + +static void lpcm_discontinuity (audio_decoder_t *this_gen) { +} + +static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; + int16_t *sample_buffer=(int16_t *)buf->content; + int stream_be; + audio_buffer_t *audio_buffer; + int format_changed = 0; + + /* Drop preview data */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + /* get config byte from mpeg2 stream */ + if ( (buf->decoder_flags & BUF_FLAG_SPECIAL) && + buf->decoder_info[1] == BUF_SPECIAL_LPCM_CONFIG ) { + unsigned int bits_per_sample = 16; + unsigned int sample_rate = 0; + unsigned int num_channels; + + num_channels = (buf->decoder_info[2] & 0x7) + 1; + switch ((buf->decoder_info[2]>>4) & 3) { + case 0: sample_rate = 48000; break; + case 1: sample_rate = 96000; break; + case 2: sample_rate = 44100; break; + case 3: sample_rate = 32000; break; + } + switch ((buf->decoder_info[2]>>6) & 3) { + case 0: bits_per_sample = 16; break; + case 1: bits_per_sample = 20; break; + case 2: bits_per_sample = 24; break; + } + + if( this->bits_per_sample != bits_per_sample || + this->number_of_channels != num_channels || + this->rate != sample_rate || + !this->output_open ) { + this->bits_per_sample = bits_per_sample; + this->number_of_channels = num_channels; + this->rate = sample_rate; + format_changed++; + } + } + + if( buf->decoder_flags & BUF_FLAG_STDHEADER ) { + this->rate=buf->decoder_info[1]; + this->bits_per_sample=buf->decoder_info[2] ; + this->number_of_channels=buf->decoder_info[3] ; + format_changed++; + } + + /* + * (re-)open output device + */ + if ( format_changed ) { + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + this->ao_cap_mode=_x_ao_channels2mode(this->number_of_channels); + + /* force 24-bit samples into 16 bits for now */ + if (this->bits_per_sample == 24) + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, + 16, + this->rate, + this->ao_cap_mode) ; + else + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, + this->bits_per_sample, + this->rate, + this->ao_cap_mode) ; + + /* stream/meta info */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Linear PCM"); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, + this->bits_per_sample * this->rate * this->number_of_channels); + } + + if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) + return; + + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + + /* Swap LPCM samples into native byte order, if necessary */ + buf->type &= 0xffff0000; + stream_be = ( buf->type == BUF_AUDIO_LPCM_BE ); + + if( this->bits_per_sample == 16 ){ + if (stream_be != this->cpu_be) + swab (sample_buffer, audio_buffer->mem, buf->size); + else + memcpy (audio_buffer->mem, sample_buffer, buf->size); + } + else if( this->bits_per_sample == 20 ) { + uint8_t *s = (uint8_t *)sample_buffer; + uint8_t *d = (uint8_t *)audio_buffer->mem; + int n = buf->size; + + if (stream_be != this->cpu_be) { + while( n >= 0 ) { + swab( s, d, 8 ); + s += 10; + d += 8; + n -= 10; + } + } else { + while( n >= 0 ) { + memcpy( d, s, 8 ); + s += 10; + d += 8; + n -= 10; + } + } + } else if( this->bits_per_sample == 24 ) { + uint8_t *s = (uint8_t *)sample_buffer; + uint8_t *d = (uint8_t *)audio_buffer->mem; + int n = buf->size; + + while (n >= 0) { + if ( stream_be ) { + *d++ = s[0]; + *d++ = s[1]; + } else { + *d++ = s[1]; + *d++ = s[2]; + } + + s += 3; + n -= 3; + } + } else { + memcpy (audio_buffer->mem, sample_buffer, buf->size); + } + + audio_buffer->vpts = buf->pts; + audio_buffer->num_frames = (((buf->size*8)/this->number_of_channels)/this->bits_per_sample); + + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + +} + +static void lpcm_dispose (audio_decoder_t *this_gen) { + lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + + free (this_gen); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + lpcm_decoder_t *this ; + + this = (lpcm_decoder_t *) xine_xmalloc (sizeof (lpcm_decoder_t)); + + this->audio_decoder.decode_data = lpcm_decode_data; + this->audio_decoder.reset = lpcm_reset; + this->audio_decoder.discontinuity = lpcm_discontinuity; + this->audio_decoder.dispose = lpcm_dispose; + + this->output_open = 0; + this->rate = 0; + this->bits_per_sample=0; + this->number_of_channels=0; + this->ao_cap_mode=0; + this->stream = stream; + + this->cpu_be = ( htons(1) == 1 ); + + return &this->audio_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + lpcm_class_t *this ; + + this = (lpcm_class_t *) xine_xmalloc (sizeof (lpcm_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "Linear PCM"; + this->decoder_class.description = N_("Linear PCM audio decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_LPCM_BE, BUF_AUDIO_LPCM_LE, 0 +}; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 16, "pcm", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/audio_dec/xine_mad_decoder.c b/src/audio_dec/xine_mad_decoder.c new file mode 100644 index 000000000..21e5bf46b --- /dev/null +++ b/src/audio_dec/xine_mad_decoder.c @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * stuff needed to turn libmad into a xine decoder plugin + */ + +#include +#include +#include + +#ifdef HAVE_MAD_H +#include +#endif + +#define LOG_MODULE "mad_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include + +#ifdef HAVE_MAD_H +# include +#else +# include "frame.h" +# include "synth.h" +#endif + +#define INPUT_BUF_SIZE 16384 + +typedef struct { + audio_decoder_class_t decoder_class; +} mad_class_t; + +typedef struct mad_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *xstream; + + int64_t pts; + + struct mad_synth synth; + struct mad_stream stream; + struct mad_frame frame; + + int output_sampling_rate; + int output_open; + int output_mode; + + uint8_t buffer[INPUT_BUF_SIZE]; + int bytes_in_buffer; + int preview_mode; + +} mad_decoder_t; + +static void mad_reset (audio_decoder_t *this_gen) { + + mad_decoder_t *this = (mad_decoder_t *) this_gen; + + mad_synth_finish (&this->synth); + mad_frame_finish (&this->frame); + mad_stream_finish(&this->stream); + + this->pts = 0; + this->bytes_in_buffer = 0; + this->preview_mode = 0; + + mad_synth_init (&this->synth); + mad_stream_init (&this->stream); + this->stream.options = MAD_OPTION_IGNORECRC; + mad_frame_init (&this->frame); +} + + +static void mad_discontinuity (audio_decoder_t *this_gen) { + + mad_decoder_t *this = (mad_decoder_t *) this_gen; + + this->pts = 0; +} + +/* utility to scale and round samples to 16 bits */ + +static inline +signed int scale(mad_fixed_t sample) +{ + /* round */ + sample += (1L << (MAD_F_FRACBITS - 16)); + + /* clip */ + if (sample >= MAD_F_ONE) + sample = MAD_F_ONE - 1; + else if (sample < -MAD_F_ONE) + sample = -MAD_F_ONE; + + /* quantize */ + return sample >> (MAD_F_FRACBITS + 1 - 16); +} + +/* +static int head_check(mad_decoder_t *this) { + + if( (this->header & 0xffe00000) != 0xffe00000) + return 0; + if(!((this->header>>17)&3)) + return 0; + if( ((this->header>>12)&0xf) == 0xf) + return 0; + if( ((this->header>>10)&0x3) == 0x3 ) + return 0; + return 1; +} +*/ + +static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + mad_decoder_t *this = (mad_decoder_t *) this_gen; + + lprintf ("decode data, decoder_flags: %d\n", buf->decoder_flags); + + if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) { + xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG, + "libmad: ALERT input buffer too small (%d bytes, %d avail)!\n", + buf->size, INPUT_BUF_SIZE-this->bytes_in_buffer); + buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer; + } + + if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) { + + /* reset decoder on leaving preview mode */ + if ((buf->decoder_flags & BUF_FLAG_PREVIEW) == 0) { + if (this->preview_mode) { + mad_reset (this_gen); + } + } else { + this->preview_mode = 1; + } + + xine_fast_memcpy (&this->buffer[this->bytes_in_buffer], + buf->content, buf->size); + this->bytes_in_buffer += buf->size; + + /* + printf ("libmad: decode data - doing it\n"); + */ + + mad_stream_buffer (&this->stream, this->buffer, + this->bytes_in_buffer); + + while (1) { + + if (mad_frame_decode (&this->frame, &this->stream) != 0) { + + if (this->stream.next_frame) { + int num_bytes = + this->buffer + this->bytes_in_buffer - this->stream.next_frame; + + /* printf("libmad: MAD_ERROR_BUFLEN\n"); */ + + memmove(this->buffer, this->stream.next_frame, num_bytes); + this->bytes_in_buffer = num_bytes; + } + + switch (this->stream.error) { + + case MAD_ERROR_BUFLEN: + return; + + default: + mad_stream_buffer (&this->stream, this->buffer, + this->bytes_in_buffer); + } + + } else { + int mode = (this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? AO_CAP_MODE_MONO : AO_CAP_MODE_STEREO; + + if (!this->output_open + || (this->output_sampling_rate != this->frame.header.samplerate) + || (this->output_mode != mode)) { + + lprintf ("audio sample rate %d mode %08x\n", this->frame.header.samplerate, mode); + + /* the mpeg audio demuxer can set audio bitrate */ + if (! _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE)) { + _x_stream_info_set(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE, + this->frame.header.bitrate); + } + + /* the mpeg audio demuxer can set this meta info */ + if (! _x_meta_info_get(this->xstream, XINE_META_INFO_AUDIOCODEC)) { + switch (this->frame.header.layer) { + case MAD_LAYER_I: + _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, + "MPEG audio layer 1 (lib: MAD)"); + break; + case MAD_LAYER_II: + _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, + "MPEG audio layer 2 (lib: MAD)"); + break; + case MAD_LAYER_III: + _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, + "MPEG audio layer 3 (lib: MAD)"); + break; + default: + _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, + "MPEG audio (lib: MAD)"); + } + } + + if (this->output_open) { + this->xstream->audio_out->close (this->xstream->audio_out, this->xstream); + this->output_open = 0; + } + if (!this->output_open) { + this->output_open = (this->xstream->audio_out->open) (this->xstream->audio_out, + this->xstream, 16, + this->frame.header.samplerate, + mode) ; + } + if (!this->output_open) { + return; + } + this->output_sampling_rate = this->frame.header.samplerate; + this->output_mode = mode; + } + + mad_synth_frame (&this->synth, &this->frame); + + if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) { + + unsigned int nchannels, nsamples; + mad_fixed_t const *left_ch, *right_ch; + struct mad_pcm *pcm = &this->synth.pcm; + audio_buffer_t *audio_buffer; + uint16_t *output; + + audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out); + output = audio_buffer->mem; + + nchannels = pcm->channels; + nsamples = pcm->length; + left_ch = pcm->samples[0]; + right_ch = pcm->samples[1]; + + while (nsamples--) { + /* output sample(s) in 16-bit signed little-endian PCM */ + + *output++ = scale(*left_ch++); + + if (nchannels == 2) + *output++ = scale(*right_ch++); + + } + + audio_buffer->num_frames = pcm->length; + audio_buffer->vpts = buf->pts; + + this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream); + + buf->pts = 0; + + } + + lprintf ("decode worked\n"); + } + } + + } +} + +static void mad_dispose (audio_decoder_t *this_gen) { + + mad_decoder_t *this = (mad_decoder_t *) this_gen; + + mad_synth_finish (&this->synth); + mad_frame_finish (&this->frame); + mad_stream_finish(&this->stream); + + if (this->output_open) { + this->xstream->audio_out->close (this->xstream->audio_out, this->xstream); + this->output_open = 0; + } + + free (this_gen); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + mad_decoder_t *this ; + + this = (mad_decoder_t *) xine_xmalloc (sizeof (mad_decoder_t)); + + this->audio_decoder.decode_data = mad_decode_data; + this->audio_decoder.reset = mad_reset; + this->audio_decoder.discontinuity = mad_discontinuity; + this->audio_decoder.dispose = mad_dispose; + + this->output_open = 0; + this->bytes_in_buffer = 0; + this->preview_mode = 0; + + this->xstream = stream; + + mad_synth_init (&this->synth); + mad_stream_init (&this->stream); + mad_frame_init (&this->frame); + + this->stream.options = MAD_OPTION_IGNORECRC; + + lprintf ("init\n"); + + return &this->audio_decoder; +} + +/* + * mad plugin class + */ +static void *init_plugin (xine_t *xine, void *data) { + + mad_class_t *this; + + this = (mad_class_t *) xine_xmalloc (sizeof (mad_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "mad"; + this->decoder_class.description = N_("libmad based mpeg audio layer 1/2/3 decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_MPEG, 0 +}; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 7 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 16, "mad", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/audio_dec/xine_musepack_decoder.c b/src/audio_dec/xine_musepack_decoder.c new file mode 100644 index 000000000..268846a1a --- /dev/null +++ b/src/audio_dec/xine_musepack_decoder.c @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +/** + * @file + * @brief xine interface to libmusepack/libmpcdec + * @author James Stembridge + * + * @todo Add support for 32-bit float samples. + * @todo Add support for seeking. + */ + +#include +#include +#include +#include +#include + +#define LOG_MODULE "mpc_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include + +#include + +#define MPC_DECODER_MEMSIZE 65536 +#define MPC_DECODER_MEMSIZE2 (MPC_DECODER_MEMSIZE/2) + +#define INIT_BUFSIZE (MPC_DECODER_MEMSIZE*2) + +typedef struct { + audio_decoder_class_t decoder_class; +} mpc_class_t; + +typedef struct mpc_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + int sample_rate; /* audio sample rate */ + int bits_per_sample; /* bits/sample, usually 8 or 16 */ + int channels; /* 1 or 2, usually */ + + int output_open; /* flag to indicate audio is ready */ + + unsigned char *buf; /* data accumulation buffer */ + unsigned int buf_max; /* maximum size of buf */ + unsigned int read; /* size of accum. data already read */ + unsigned int size; /* size of accumulated data in buf */ + + mpc_reader reader; + mpc_streaminfo streaminfo; + mpc_decoder decoder; + + int decoder_ok; + unsigned int current_frame; + + int32_t file_size; + +} mpc_decoder_t; + + +/************************************************************************** + * musepack specific functions + *************************************************************************/ + +/* Reads size bytes of data into buffer at ptr. */ +static int32_t mpc_reader_read(void *const data, void *const ptr, int size) { + mpc_decoder_t *const this = (mpc_decoder_t *) data; + + lprintf("mpc_reader_read: size=%d\n", size); + + /* Don't try to read more data than we have */ + if (size > (this->size - this->read)) + size = this->size - this->read; + + /* Copy the data */ + xine_fast_memcpy(ptr, &this->buf[this->read], size); + + /* Update our position in the data buffer */ + this->read += size; + + return size; +} + +/* Seeks to byte position offset. */ +static mpc_bool_t mpc_reader_seek(void *const data, const int32_t offset) { + mpc_decoder_t *const this = (mpc_decoder_t *) data; + + lprintf("mpc_reader_seek: offset=%d\n", offset); + + /* seek is only called when reading the header so we can assume + * that the buffer starts at the start of the file */ + this->read = offset; + + return TRUE; +} + +/* Returns the current byte offset in the stream. */ +static int32_t mpc_reader_tell(void *const data) { + lprintf("mpc_reader_tell\n"); + + /* Tell isn't used so just return 0 */ + return 0; +} + +/* Returns the total length of the source stream, in bytes. */ +static int32_t mpc_reader_get_size(void *const data) { + mpc_decoder_t *const this = (mpc_decoder_t *) data; + + lprintf("mpc_reader_get_size\n"); + + return this->file_size; +} + +/* True if the stream is a seekable stream. */ +static mpc_bool_t mpc_reader_canseek(void *data) { + lprintf("mpc_reader_canseek\n"); + + return TRUE; +} + +/** + * @brief Convert a array of floating point samples into 16-bit signed integer samples + * @param f Floating point samples array (origin) + * @param s16 16-bit signed integer samples array (destination) + * @param samples Number of samples to convert + * + * @todo This same work is being done in many decoders to adapt the output of + * the decoder to what the audio output can actually use, this should be + * done by the audio_output loop, not by the decoders. + */ +static inline void float_to_int(const float *const _f, int16_t *const s16, const int samples) { + int i; + for (i = 0; i < samples; i++) { + const float f = _f[i] * 32767; + if (f > INT16_MAX) + s16[i] = INT16_MAX; + else if (f < INT16_MIN) + s16[i] = INT16_MIN; + else + s16[i] = f; + /* printf("samples[%d] = %f, %d\n", i, _f[i], s16[num_channels*i]); */ + } +} + +/* Decode a musepack frame */ +static int mpc_decode_frame (mpc_decoder_t *this) { + float buffer[MPC_DECODER_BUFFER_LENGTH]; + uint32_t frames; + + lprintf("mpd_decode_frame\n"); + + frames = mpc_decoder_decode(&this->decoder, buffer, 0, 0); + + if (frames > 0) { + audio_buffer_t *audio_buffer; + int16_t *int_samples; + + lprintf("got %d samples\n", frames); + + /* Get audio buffer */ + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + audio_buffer->vpts = 0; + audio_buffer->num_frames = frames; + + /* Convert samples */ + int_samples = (int16_t *) audio_buffer->mem; + float_to_int(buffer, int_samples, frames*this->channels); + + /* Output converted samples */ + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + } + + return frames; +} + +/************************************************************************** + * xine audio plugin functions + *************************************************************************/ + +static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + mpc_decoder_t *this = (mpc_decoder_t *) this_gen; + int err; + + lprintf("mpc_decode_data\n"); + + if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED)) + return; + + /* We don't handle special buffers */ + if (buf->decoder_flags & BUF_FLAG_SPECIAL) + return; + + /* Read header */ + if (buf->decoder_flags & BUF_FLAG_HEADER) { + + lprintf("header\n"); + + /* File size is in decoder_info[0] */ + this->file_size = buf->decoder_info[0]; + + /* Initialise the data accumulation buffer */ + this->buf = xine_xmalloc(INIT_BUFSIZE); + this->buf_max = INIT_BUFSIZE; + this->read = 0; + this->size = 0; + + /* Initialise the reader */ + this->reader.read = mpc_reader_read; + this->reader.seek = mpc_reader_seek; + this->reader.tell = mpc_reader_tell; + this->reader.get_size = mpc_reader_get_size; + this->reader.canseek = mpc_reader_canseek; + this->reader.data = this; + + /* Copy header to buffer */ + xine_fast_memcpy(this->buf, buf->content, buf->size); + this->size = buf->size; + + /* Initialise and read stream info */ + mpc_streaminfo_init(&this->streaminfo); + + if ((err = mpc_streaminfo_read(&this->streaminfo, &this->reader))) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("libmusepack: mpc_streaminfo_read failed: %d\n"), err); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + return; + } + + this->sample_rate = this->streaminfo.sample_freq; + this->channels = this->streaminfo.channels; + this->bits_per_sample = 16; + + /* After the header the demuxer starts sending data from an offset + * of 28 bytes */ + this->size = 28; + + /* We need to keep track of the current frame so we now when we've + * reached the end of the stream */ + this->current_frame = 0; + + /* Setup the decoder */ + mpc_decoder_setup(&this->decoder, &this->reader); + this->decoder_ok = 0; + + /* Take this opportunity to initialize stream/meta information */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, + "Musepack (libmusepack)"); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, + (int) this->streaminfo.average_bitrate); + + return; + } + + lprintf("data: %u size=%u read=%u\n", buf->size, this->size, this->read); + + /* if the audio output is not open yet, open the audio output */ + if (!this->output_open) { + this->output_open = (this->stream->audio_out->open) ( + this->stream->audio_out, + this->stream, + this->bits_per_sample, + this->sample_rate, + _x_ao_channels2mode(this->channels)); + } + + /* if the audio still isn't open, do not go any further with the decode */ + if (!this->output_open) + return; + + /* If we run out of space in our internal buffer we discard what's + * already been read */ + if (((this->size + buf->size) > this->buf_max) && this->read) { + lprintf("discarding read data\n"); + this->size -= this->read; + memmove(this->buf, &this->buf[this->read], this->size); + this->read = 0; + } + + /* If there still isn't space we have to increase the size of the + * internal buffer */ + if ((this->size + buf->size) > this->buf_max) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libmusepack: increasing internal buffer size\n"); + this->buf_max += 2*buf->size; + this->buf = realloc(this->buf, this->buf_max); + } + + /* Copy data */ + xine_fast_memcpy(&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + /* Time to decode */ + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + /* Increment frame count */ + if (this->current_frame++ == this->streaminfo.frames) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("libmusepack: data after last frame ignored\n")); + return; + } + + if (!this->decoder_ok) { + /* We require MPC_DECODER_MEMSIZE bytes to initialise the decoder */ + if ((this->size - this->read) >= MPC_DECODER_MEMSIZE) { + lprintf("initialise"); + + if (!mpc_decoder_initialize(&this->decoder, &this->streaminfo)) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("libmusepack: mpc_decoder_initialise failed\n")); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + return; + } + + this->decoder_ok = 1; + } else { + /* Not enough data yet */ + return; + } + } + + /* mpc_decoder_decode may cause a read of MPC_DECODER_MEMSIZE/2 bytes so + * make sure we have enough data available */ + if ((this->size - this->read) >= MPC_DECODER_MEMSIZE2) { + lprintf("decoding\n"); + + if ((err = mpc_decode_frame(this)) < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("libmusepack: mpc_decoder_decode failed: %d\n"), err); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + return; + } + } + + /* If we are at the end of the stream we decode the remaining frames as we + * know we'll have enough data */ + if (this->current_frame == this->streaminfo.frames) { + lprintf("flushing buffers\n"); + + do { + if ((err = mpc_decode_frame(this)) < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("libmusepack: mpc_decoder_decode failed: %d\n"), err); + } + } while (err > 0); + + lprintf("buffers flushed\n"); + } + } +} + +static void mpc_reset (audio_decoder_t *this_gen) { + mpc_decoder_t *this = (mpc_decoder_t *) this_gen; + + this->size = 0; + this->read = 0; +} + +static void mpc_discontinuity (audio_decoder_t *this_gen) { + /* mpc_decoder_t *this = (mpc_decoder_t *) this_gen; */ +} + +static void mpc_dispose (audio_decoder_t *this_gen) { + + mpc_decoder_t *this = (mpc_decoder_t *) this_gen; + + /* close the audio output */ + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + /* free anything that was allocated during operation */ + free(this->buf); + + free(this); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + mpc_decoder_t *this ; + + this = (mpc_decoder_t *) xine_xmalloc (sizeof (mpc_decoder_t)); + + /* connect the member functions */ + this->audio_decoder.decode_data = mpc_decode_data; + this->audio_decoder.reset = mpc_reset; + this->audio_decoder.discontinuity = mpc_discontinuity; + this->audio_decoder.dispose = mpc_dispose; + + /* connect the stream */ + this->stream = stream; + + /* audio output is not open at the start */ + this->output_open = 0; + + /* no buffer yet */ + this->buf = NULL; + + /* initialize the basic audio parameters */ + this->channels = 0; + this->sample_rate = 0; + this->bits_per_sample = 0; + + /* return the newly-initialized audio decoder */ + return &this->audio_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + mpc_class_t *this ; + + this = (mpc_class_t *) xine_xmalloc (sizeof (mpc_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "mpc"; + this->decoder_class.description = N_("mpc: musepack audio decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_MPC, + 0 +}; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 5 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* { type, API version, "name", version, special_info, init_function }, */ + { PLUGIN_AUDIO_DECODER, 16, "mpc", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + diff --git a/src/libxineadec/Makefile.am b/src/libxineadec/Makefile.am deleted file mode 100644 index a85497bbf..000000000 --- a/src/libxineadec/Makefile.am +++ /dev/null @@ -1,85 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -EXTRA_DIST = fooaudio.c - -if ENABLE_MUSEPACK -musepack_module = xineplug_decode_mpc.la -endif - -if ENABLE_DTS -dts_module = xineplug_decode_dts.la -endif - -if ENABLE_MAD -mad_module = xineplug_decode_mad.la -endif - -if ENABLE_A52DEC -a52_module = xineplug_decode_a52.la -endif - -if ENABLE_FAAD -faad_module = xineplug_decode_faad.la -endif - -$(top_builddir)/contrib/a52dec/liba52.la: - $(MAKE) -C $(top_builddir)/contrib/a52dec - -$(top_builddir)/contrib/libfaad/libfaad.la: - $(MAKE) -C $(top_builddir)/contrib/libfaad - -$(top_builddir)/contrib/libmad/libmad.la: - $(MAKE) -C $(top_builddir)/contrib/libmad - -$(top_builddir)/contrib/libmpcdec/libmpcdec.la: - $(MAKE) -C $(top_builddir)/contrib/libmpcdec - -$(top_builddir)/contrib/libdca/libdca.la: - $(MAKE) -C $(top_builddir)/contrib/libdca - -$(top_builddir)/contrib/gsm610/libgsm610.la: - $(MAKE) -C $(top_builddir)/contrib/gsm610 - -xineplug_LTLIBRARIES = \ - xineplug_decode_gsm610.la \ - xineplug_decode_lpcm.la \ - $(musepack_module) \ - $(dts_module) \ - $(mad_module) \ - $(a52_module) \ - $(faad_module) - -xineplug_decode_gsm610_la_SOURCES = gsm610.c -xineplug_decode_gsm610_la_LIBADD = $(XINE_LIB) $(top_builddir)/contrib/gsm610/libgsm610.la -xineplug_decode_gsm610_la_CPPFLAGS = -I$(top_srcdir)/contrib/gsm610 - -xineplug_decode_lpcm_la_SOURCES = xine_lpcm_decoder.c -xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB) - -xineplug_decode_mpc_la_SOURCES = xine_musepack_decoder.c -xineplug_decode_mpc_la_DEPENDENCIES = $(MPCDEC_DEPS) -xineplug_decode_mpc_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(MPCDEC_LIBS) -xineplug_decode_mpc_la_CFLAGS = $(AM_CFLAGS) $(MPCDEC_CFLAGS) - -xineplug_decode_dts_la_SOURCES = xine_dts_decoder.c -xineplug_decode_dts_la_DEPENDENCIES = $(LIBDTS_DEPS) -xineplug_decode_dts_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(LIBDTS_LIBS) -xineplug_decode_dts_la_CFLAGS = $(AM_CFLAGS) $(LIBDTS_CFLAGS) - -xineplug_decode_mad_la_SOURCES = xine_mad_decoder.c -xineplug_decode_mad_la_DEPENDENCIES = $(LIBMAD_DEPS) -xineplug_decode_mad_la_LIBADD = $(XINE_LIB) $(LIBMAD_LIBS) -xineplug_decode_mad_la_CFLAGS = $(AM_CFLAGS) $(LIBMAD_CFLAGS) - -xineplug_decode_a52_la_SOURCES = xine_a52_decoder.c -xineplug_decode_a52_la_DEPENDENCIES = $(A52DEC_DEPS) -xineplug_decode_a52_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(A52DEC_LIBS) -lm -xineplug_decode_a52_la_CFLAGS = $(AM_CFLAGS) $(A52DEC_CFLAGS) - -xineplug_decode_faad_la_SOURCES = xine_faad_decoder.c -xineplug_decode_faad_la_DEPENDENCIES = $(FAAD_DEPS) -xineplug_decode_faad_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(FAAD_LIBS) -lm -xineplug_decode_faad_la_CFLAGS = $(FAAD_CFLAGS) diff --git a/src/libxineadec/fooaudio.c b/src/libxineadec/fooaudio.c deleted file mode 100644 index b0ef63454..000000000 --- a/src/libxineadec/fooaudio.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2000-2001 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * fooaudio.c: This is a reference audio decoder for the xine multimedia - * player. It really works too! It will output a continuous sine wave in - * place of the data it should actually send. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -/* math.h required for fooaudio sine wave generation */ -#include - -#define AUDIOBUFSIZE 128*1024 - -typedef struct { - audio_decoder_class_t decoder_class; -} fooaudio_class_t; - -typedef struct fooaudio_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - int sample_rate; /* audio sample rate */ - int bits_per_sample; /* bits/sample, usually 8 or 16 */ - int channels; /* 1 or 2, usually */ - - int output_open; /* flag to indicate audio is ready */ - - unsigned char *buf; /* data accumulation buffer */ - int bufsize; /* maximum size of buf */ - int size; /* size of accumulated data in buf */ - - /* fooaudio-specific variables */ - int64_t last_pts; - unsigned int iteration; - -} fooaudio_decoder_t; - -/************************************************************************** - * fooaudio specific decode functions - *************************************************************************/ - -/************************************************************************** - * xine audio plugin functions - *************************************************************************/ - -static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - audio_buffer_t *audio_buffer; - int i; - int64_t samples_to_generate; - int samples_to_send; - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - - /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize - * the decoder. The buffer element type has 4 decoder_info fields, - * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field - * 3 is the number of channels. */ - this->sample_rate = buf->decoder_info[1]; - this->bits_per_sample = buf->decoder_info[2]; - this->channels = buf->decoder_info[3]; - - /* initialize the data accumulation buffer */ - this->buf = xine_xmalloc(AUDIOBUFSIZE); - this->bufsize = AUDIOBUFSIZE; - this->size = 0; - - /* take this opportunity to initialize stream/meta information */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "fooaudio"); - - /* perform any other required initialization */ - this->last_pts = -1; - this->iteration = 0; - - return; - } - - /* if the audio output is not open yet, open the audio output */ -#warning: Audio output is hardcoded to mono 16-bit PCM - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) ( - this->stream->audio_out, - this->stream, -/* this->bits_per_sample, */ - 16, - this->sample_rate, -/* _x_ao_channels2mode(this->channels));*/ - AO_CAP_MODE_MONO); - } - - /* if the audio still isn't open, do not go any further with the decode */ - if (!this->output_open) - return; - - /* accumulate the data passed through the buffer element type; increase - * the accumulator buffer size as necessary */ - if( this->size + buf->size > this->bufsize ) { - this->bufsize = this->size + 2 * buf->size; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "fooaudio: increasing source buffer to %d to avoid overflow.\n", this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); - } - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - /* When a buffer element type has the BUF_FLAG_FRAME_END flag set, it is - * time to decode the data in the buffer. */ - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - /* This is where the real meat of the audio decoder is implemented. - * The general strategy is to decode the data in the accumulation buffer - * into raw PCM data and then dispatch the PCM to the engine in smaller - * buffers. What follows in the inside of this scope is the meat of - * this particular audio decoder. */ - - /* Operation of the fooaudio decoder: - * This decoder generates a continuous sine pattern based on the pts - * values sent by the xine engine. Two pts values are needed to know - * how long to make the audio. Thus, If this is the first frame or - * a seek has occurred (indicated by this->last_pts = -1), - * log the pts but do not create any audio. - * - * When a valid pts delta is generated, create n audio samples, where - * n is given as: - * - * n pts delta - * ----------- = --------- => n = (pts delta * sample rate) / 90000 - * sample rate 90000 - * - */ - - if (this->last_pts != -1) { - - /* no real reason to set this variable to 0 first; I just wanted the - * novelty of using all 4 basic arithmetic ops in a row (+ - * /) */ - samples_to_generate = 0; - samples_to_generate += buf->pts; - samples_to_generate -= this->last_pts; - samples_to_generate *= this->sample_rate; - samples_to_generate /= 90000; - - /* save the pts now since it will likely be trashed later */ - this->last_pts = buf->pts; - - while (samples_to_generate) { - - /* get an audio buffer */ - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - if (audio_buffer->mem_size == 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "fooaudio: Help! Allocated audio buffer with nothing in it!\n"); - return; - } - - /* samples_to_generate is a sample count; mem_size is a byte count */ - if (samples_to_generate > audio_buffer->mem_size / 2) - samples_to_send = audio_buffer->mem_size / 2; - else - samples_to_send = samples_to_generate; - samples_to_generate -= samples_to_send; - -#define WAVE_HZ 300 - /* fill up the samples in the buffer */ - for (i = 0; i < samples_to_send; i++) - audio_buffer->mem[i] = - (short)(sin(2 * M_PI * this->iteration++ / WAVE_HZ) * 32767); - - /* final prep for audio buffer dispatch */ - audio_buffer->num_frames = samples_to_send; - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - } - } else { - /* log the pts for the next time */ - this->last_pts = buf->pts; - } - - /* reset data accumulation buffer */ - this->size = 0; - } -} - -/* This function resets the state of the audio decoder. This usually - * entails resetting the data accumulation buffer. */ -static void fooaudio_reset (audio_decoder_t *this_gen) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - - this->size = 0; - - /* this is specific to fooaudio */ - this->last_pts = -1; -} - -/* This function resets the last pts value of the audio decoder. */ -static void fooaudio_discontinuity (audio_decoder_t *this_gen) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - - /* this is specific to fooaudio */ - this->last_pts = -1; -} - -/* This function closes the audio output and frees the private audio decoder - * structure. */ -static void fooaudio_dispose (audio_decoder_t *this_gen) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - - /* close the audio output */ - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - /* free anything that was allocated during operation */ - free(this->buf); - free(this); -} - -/* This function allocates, initializes, and returns a private audio - * decoder structure. */ -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - fooaudio_decoder_t *this ; - - this = (fooaudio_decoder_t *) xine_xmalloc (sizeof (fooaudio_decoder_t)); - - /* connect the member functions */ - this->audio_decoder.decode_data = fooaudio_decode_data; - this->audio_decoder.reset = fooaudio_reset; - this->audio_decoder.discontinuity = fooaudio_discontinuity; - this->audio_decoder.dispose = fooaudio_dispose; - - /* connect the stream */ - this->stream = stream; - - /* audio output is not open at the start */ - this->output_open = 0; - - /* initialize the basic audio parameters */ - this->channels = 0; - this->sample_rate = 0; - this->bits_per_sample = 0; - - /* initialize the data accumulation buffer */ - this->buf = NULL; - this->bufsize = 0; - this->size = 0; - - /* return the newly-initialized audio decoder */ - return &this->audio_decoder; -} - -/* This function frees the audio decoder class and any other memory that was - * allocated. */ -static void dispose_class (audio_decoder_class_t *this_gen) { - - fooaudio_class_t *this = (fooaudio_class_t *)this_gen; - - free (this); -} - -/* This function allocates a private audio decoder class and initializes - * the class's member functions. */ -static void *init_plugin (xine_t *xine, void *data) { - - fooaudio_class_t *this ; - - this = (fooaudio_class_t *) xine_malloc (sizeof (fooaudio_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "fooaudio"; - this->decoder_class.description = N_("fooaudio: reference xine audio decoder plugin"); - this->decoder_class.dispose = dispose_class; - - return this; -} - -/* This is a list of all of the internal xine audio buffer types that - * this decoder is able to handle. Check src/xine-engine/buffer.h for a - * list of valid buffer types (and add a new one if the one you need does - * not exist). Terminate the list with a 0. */ -static uint32_t audio_types[] = { - /* BUF_AUDIO_FOO, */ - 0 -}; - -/* This data structure combines the list of supported xine buffer types and - * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) - * will be used instead of a plugin with priority (n). */ -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -/* The plugin catalog entry. This is the only information that this plugin - * will export to the public. */ -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* { type, API version, "name", version, special_info, init_function }, */ - { PLUGIN_AUDIO_DECODER, 16, "fooaudio", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - diff --git a/src/libxineadec/gsm610.c b/src/libxineadec/gsm610.c deleted file mode 100644 index 8192aa7d8..000000000 --- a/src/libxineadec/gsm610.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * GSM 6.10 Audio Decoder - * This decoder is based on the GSM 6.10 codec library found at: - * http://kbs.cs.tu-berlin.de/~jutta/toast.html - * Additionally, here is an article regarding the software that appeared - * in Dr. Dobbs Journal: - * http://www.ddj.com/documents/s=1012/ddj9412b/9412b.htm - * - * This is the notice that comes with the software: - * -------------------------------------------------------------------- - * Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, - * Technische Universitaet Berlin - * - * Any use of this software is permitted provided that this notice is not - * removed and that neither the authors nor the Technische Universitaet Berlin - * are deemed to have made any representations as to the suitability of this - * software for any purpose nor are held responsible for any defects of - * this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - * - * As a matter of courtesy, the authors request to be informed about uses - * this software has found, about bugs in this software, and about any - * improvements that may be of general interest. - * - * Berlin, 28.11.1994 - * Jutta Degener - * Carsten Bormann - * -------------------------------------------------------------------- - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#include "private.h" -#include "gsm.h" - -#define AUDIOBUFSIZE 128*1024 - -#define GSM610_SAMPLE_SIZE 16 -#define GSM610_BLOCK_SIZE 160 - -typedef struct { - audio_decoder_class_t decoder_class; -} gsm610_class_t; - -typedef struct gsm610_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - unsigned int buf_type; - int output_open; - int sample_rate; - - unsigned char *buf; - int bufsize; - int size; - - gsm gsm_state; - -} gsm610_decoder_t; - -/************************************************************************** - * xine audio plugin functions - *************************************************************************/ - -static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen; - audio_buffer_t *audio_buffer; - int in_ptr; - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - this->sample_rate = buf->decoder_info[1]; - - this->buf = xine_xmalloc(AUDIOBUFSIZE); - this->bufsize = AUDIOBUFSIZE; - this->size = 0; - - /* stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "GSM 6.10"); - - return; - } - - if (!this->output_open) { - - this->gsm_state = gsm_create(); - this->buf_type = buf->type; - - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, GSM610_SAMPLE_SIZE, this->sample_rate, AO_CAP_MODE_MONO); - } - - /* if the audio still isn't open, bail */ - if (!this->output_open) - return; - - if( this->size + buf->size > this->bufsize ) { - this->bufsize = this->size + 2 * buf->size; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "gsm610: increasing source buffer to %d to avoid overflow.\n", this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ - int16_t decode_buffer[GSM610_BLOCK_SIZE]; - - /* handle the Microsoft variant of GSM data */ - if (this->buf_type == BUF_AUDIO_MSGSM) { - - this->gsm_state->wav_fmt = 1; - - /* the data should line up on a 65-byte boundary */ - if ((buf->size % 65) != 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "gsm610: received MS GSM block that does not line up\n"); - this->size = 0; - return; - } - - in_ptr = 0; - while (this->size) { - gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer); - if ((in_ptr % 65) == 0) { - in_ptr += 33; - this->size -= 33; - } else { - in_ptr += 32; - this->size -= 32; - } - - /* dispatch the decoded audio; assume that the audio buffer will - * always contain at least 160 samples */ - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - xine_fast_memcpy(audio_buffer->mem, decode_buffer, - GSM610_BLOCK_SIZE * 2); - audio_buffer->num_frames = GSM610_BLOCK_SIZE; - - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - } - } else { - - /* handle the other variant, which consists of 33-byte blocks */ - this->gsm_state->wav_fmt = 0; - - /* the data should line up on a 33-byte boundary */ - if ((buf->size % 33) != 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: received GSM block that does not line up\n"); - this->size = 0; - return; - } - - in_ptr = 0; - while (this->size) { - gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer); - in_ptr += 33; - this->size -= 33; - - /* dispatch the decoded audio; assume that the audio buffer will - * always contain at least 160 samples */ - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - xine_fast_memcpy(audio_buffer->mem, decode_buffer, - GSM610_BLOCK_SIZE * 2); - audio_buffer->num_frames = GSM610_BLOCK_SIZE; - - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - } - } - } -} - -static void gsm610_reset (audio_decoder_t *this_gen) { -} - -static void gsm610_discontinuity (audio_decoder_t *this_gen) { -} - -static void gsm610_dispose (audio_decoder_t *this_gen) { - - gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen; - - if (this->gsm_state) - gsm_destroy(this->gsm_state); - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - if (this->buf) - free(this->buf); - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - gsm610_decoder_t *this ; - - this = (gsm610_decoder_t *) xine_xmalloc (sizeof (gsm610_decoder_t)); - - this->audio_decoder.decode_data = gsm610_decode_data; - this->audio_decoder.reset = gsm610_reset; - this->audio_decoder.discontinuity = gsm610_discontinuity; - this->audio_decoder.dispose = gsm610_dispose; - - this->output_open = 0; - this->sample_rate = 0; - this->stream = stream; - this->buf = NULL; - this->size = 0; - - return &this->audio_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - gsm610_class_t *this ; - - this = (gsm610_class_t *) xine_xmalloc (sizeof (gsm610_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "GSM 6.10"; - this->decoder_class.description = N_("GSM 6.10 audio decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_MSGSM, - BUF_AUDIO_GSM610, - 0 -}; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 9 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 16, "gsm610", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_a52_decoder.c b/src/libxineadec/xine_a52_decoder.c deleted file mode 100644 index e34504553..000000000 --- a/src/libxineadec/xine_a52_decoder.c +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stuff needed to turn liba52 into a xine decoder plugin - */ - -#ifndef __sun -/* required for swab() */ -#define _XOPEN_SOURCE 500 -#endif -/* avoid compiler warnings */ -#define _BSD_SOURCE 1 - -#include - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "a52_decoder" -#define LOG_VERBOSE -/* -#define LOG -#define LOG_PTS -*/ - -#include -#include - -#ifdef HAVE_A52DEC_A52_H -# include -#else -# include "a52.h" -#endif - -#ifdef HAVE_A52DEC_A52_INTERNAL_H -# include -#else -# include "a52_internal.h" -#endif - -#include -#include - -#include "../../contrib/a52dec/crc.c" - -#undef DEBUG_A52 -#ifdef DEBUG_A52 -int a52file; -#endif - -typedef struct { - audio_decoder_class_t decoder_class; - config_values_t *config; - - float a52_level; - int disable_dynrng_compress; - int enable_surround_downmix; - -} a52dec_class_t; - -typedef struct a52dec_decoder_s { - audio_decoder_t audio_decoder; - - a52dec_class_t *class; - xine_stream_t *stream; - int64_t pts; - int64_t pts_list[5]; - int32_t pts_list_position; - - uint8_t frame_buffer[3840]; - uint8_t *frame_ptr; - int sync_state; - int frame_length, frame_todo; - uint16_t syncword; - - a52_state_t *a52_state; - int a52_flags; - int a52_bit_rate; - int a52_sample_rate; - int have_lfe; - - int a52_flags_map[11]; - int ao_flags_map[11]; - - int audio_caps; - int bypass_mode; - int output_sampling_rate; - int output_open; - int output_mode; - -} a52dec_decoder_t; - -struct frmsize_s -{ - uint16_t bit_rate; - uint16_t frm_size[3]; -}; - -static const struct frmsize_s frmsizecod_tbl[64] = -{ - { 32 ,{64 ,69 ,96 } }, - { 32 ,{64 ,70 ,96 } }, - { 40 ,{80 ,87 ,120 } }, - { 40 ,{80 ,88 ,120 } }, - { 48 ,{96 ,104 ,144 } }, - { 48 ,{96 ,105 ,144 } }, - { 56 ,{112 ,121 ,168 } }, - { 56 ,{112 ,122 ,168 } }, - { 64 ,{128 ,139 ,192 } }, - { 64 ,{128 ,140 ,192 } }, - { 80 ,{160 ,174 ,240 } }, - { 80 ,{160 ,175 ,240 } }, - { 96 ,{192 ,208 ,288 } }, - { 96 ,{192 ,209 ,288 } }, - { 112 ,{224 ,243 ,336 } }, - { 112 ,{224 ,244 ,336 } }, - { 128 ,{256 ,278 ,384 } }, - { 128 ,{256 ,279 ,384 } }, - { 160 ,{320 ,348 ,480 } }, - { 160 ,{320 ,349 ,480 } }, - { 192 ,{384 ,417 ,576 } }, - { 192 ,{384 ,418 ,576 } }, - { 224 ,{448 ,487 ,672 } }, - { 224 ,{448 ,488 ,672 } }, - { 256 ,{512 ,557 ,768 } }, - { 256 ,{512 ,558 ,768 } }, - { 320 ,{640 ,696 ,960 } }, - { 320 ,{640 ,697 ,960 } }, - { 384 ,{768 ,835 ,1152 } }, - { 384 ,{768 ,836 ,1152 } }, - { 448 ,{896 ,975 ,1344 } }, - { 448 ,{896 ,976 ,1344 } }, - { 512 ,{1024 ,1114 ,1536 } }, - { 512 ,{1024 ,1115 ,1536 } }, - { 576 ,{1152 ,1253 ,1728 } }, - { 576 ,{1152 ,1254 ,1728 } }, - { 640 ,{1280 ,1393 ,1920 } }, - { 640 ,{1280 ,1394 ,1920 } } -}; - -/* config callbacks */ -static void a52_level_change_cb(void *this_gen, xine_cfg_entry_t *entry); -static void dynrng_compress_change_cb(void *this_gen, xine_cfg_entry_t *entry); -static void surround_downmix_change_cb(void *this_gen, xine_cfg_entry_t *entry); - - -static void a52dec_reset (audio_decoder_t *this_gen) { - - a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; - - this->syncword = 0; - this->sync_state = 0; - this->pts = 0; - this->pts_list[0] = 0; - this->pts_list_position = 0; -} - -static void a52dec_discontinuity (audio_decoder_t *this_gen) { - - a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; - - this->pts = 0; - this->pts_list[0] = 0; - this->pts_list_position = 0; -} - -static inline int16_t blah (int32_t i) { - - if (i > 0x43c07fff) - return 32767; - else if (i < 0x43bf8000) - return -32768; - else - return i - 0x43c00000; -} - -static inline void float_to_int (float * _f, int16_t * s16, int num_channels) { - int i; - int32_t * f = (int32_t *) _f; /* XXX assumes IEEE float format */ - - for (i = 0; i < 256; i++) { - s16[num_channels*i] = blah (f[i]); - } -} - -static inline void mute_channel (int16_t * s16, int num_channels) { - int i; - - for (i = 0; i < 256; i++) { - s16[num_channels*i] = 0; - } -} - -static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts, int preview_mode) { - - int output_mode = AO_CAP_MODE_STEREO; - - /* - * do we want to decode this frame in software? - */ -#ifdef LOG_PTS - printf("a52dec:decode_frame:pts=%lld\n",pts); -#endif - if (!this->bypass_mode) { - - int a52_output_flags, i; - sample_t level = this->class->a52_level; - audio_buffer_t *buf; - int16_t *int_samples; - sample_t *samples = a52_samples(this->a52_state); - - /* - * oki, decode this frame in software - */ - - /* determine output mode */ - - a52_output_flags = this->a52_flags_map[this->a52_flags & A52_CHANNEL_MASK]; - - if (a52_frame (this->a52_state, - this->frame_buffer, - &a52_output_flags, - &level, 384)) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: a52_frame error\n"); - return; - } - - if (this->class->disable_dynrng_compress) - a52_dynrng (this->a52_state, NULL, NULL); - - this->have_lfe = a52_output_flags & A52_LFE; - if (this->have_lfe) - if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { - output_mode = AO_CAP_MODE_5_1CHANNEL; - } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { - output_mode = AO_CAP_MODE_4_1CHANNEL; - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: WHAT DO I DO!!!\n"); - output_mode = this->ao_flags_map[a52_output_flags]; - } - else - output_mode = this->ao_flags_map[a52_output_flags]; - /* - * (re-)open output device - */ - - if (!this->output_open - || (this->a52_sample_rate != this->output_sampling_rate) - || (output_mode != this->output_mode)) { - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, 16, - this->a52_sample_rate, - output_mode) ; - this->output_sampling_rate = this->a52_sample_rate; - this->output_mode = output_mode; - } - - - if (!this->output_open || preview_mode) - return; - - - /* - * decode a52 and convert/interleave samples - */ - - buf = this->stream->audio_out->get_buffer (this->stream->audio_out); - int_samples = buf->mem; - buf->num_frames = 256*6; - - for (i = 0; i < 6; i++) { - if (a52_block (this->a52_state)) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: a52_block error on audio channel %d\n", i); -#if 0 - for(n=0;n<2000;n++) { - printf("%02x ",this->frame_buffer[n]); - if ((n % 32) == 0) printf("\n"); - } - printf("\n"); -#endif - buf->num_frames = 0; - break; - } - - switch (output_mode) { - case AO_CAP_MODE_MONO: - float_to_int (&samples[0], int_samples+(i*256), 1); - break; - case AO_CAP_MODE_STEREO: - float_to_int (&samples[0*256], int_samples+(i*256*2), 2); - float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2); - break; - case AO_CAP_MODE_4CHANNEL: - float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */ - float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */ - float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */ - float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */ - break; - case AO_CAP_MODE_4_1CHANNEL: - float_to_int (&samples[0*256], int_samples+(i*256*6)+5, 6); /* LFE */ - float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ - float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ - float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ - float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ - mute_channel ( int_samples+(i*256*6)+4, 6); /* C */ - break; - case AO_CAP_MODE_5CHANNEL: - float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ - float_to_int (&samples[1*256], int_samples+(i*256*6)+4, 6); /* C */ - float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ - float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ - float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ - mute_channel ( int_samples+(i*256*6)+5, 6); /* LFE */ - break; - case AO_CAP_MODE_5_1CHANNEL: - float_to_int (&samples[0*256], int_samples+(i*256*6)+5, 6); /* lfe */ - float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ - float_to_int (&samples[2*256], int_samples+(i*256*6)+4, 6); /* C */ - float_to_int (&samples[3*256], int_samples+(i*256*6)+1, 6); /* R */ - float_to_int (&samples[4*256], int_samples+(i*256*6)+2, 6); /* RL */ - float_to_int (&samples[5*256], int_samples+(i*256*6)+3, 6); /* RR */ - break; - default: - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: help - unsupported mode %08x\n", output_mode); - } - } - - lprintf ("%d frames output\n", buf->num_frames); - - /* output decoded samples */ - - buf->vpts = pts; - - this->stream->audio_out->put_buffer (this->stream->audio_out, buf, this->stream); - - } else { - - /* - * loop through a52 data - */ - - if (!this->output_open) { - - int sample_rate, bit_rate, flags; - - a52_syncinfo (this->frame_buffer, &flags, &sample_rate, &bit_rate); - - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, 16, - sample_rate, - AO_CAP_MODE_A52) ; - this->output_mode = AO_CAP_MODE_A52; - } - - if (this->output_open && !preview_mode) { - /* SPDIF Passthrough - * Build SPDIF Header and encaps the A52 audio data in it. - */ - uint32_t syncword, crc1, fscod,frmsizecod,bsid,bsmod,frame_size; - uint8_t *data_out,*data_in; - audio_buffer_t *buf = this->stream->audio_out->get_buffer (this->stream->audio_out); - data_in=(uint8_t *) this->frame_buffer; - data_out=(uint8_t *) buf->mem; - syncword = data_in[0] | (data_in[1] << 8); - crc1 = data_in[2] | (data_in[3] << 8); - fscod = (data_in[4] >> 6) & 0x3; - frmsizecod = data_in[4] & 0x3f; - bsid = (data_in[5] >> 3) & 0x1f; - bsmod = data_in[5] & 0x7; /* bsmod, stream = 0 */ - frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] ; - - data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */ - data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */ - data_out[4] = 0x01; /* AC3 data */ - data_out[5] = bsmod; /* bsmod, stream = 0 */ - data_out[6] = (frame_size << 4) & 0xff; /* frame_size * 16 */ - data_out[7] = ((frame_size ) >> 4) & 0xff; - swab(data_in, &data_out[8], frame_size * 2 ); - - buf->num_frames = 1536; - buf->vpts = pts; - - this->stream->audio_out->put_buffer (this->stream->audio_out, buf, this->stream); - - } - } -} - -static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; - uint8_t *current = buf->content; - uint8_t *sync_start=current + 1; - uint8_t *end = buf->content + buf->size; - uint8_t byte; - int32_t n; - uint16_t crc16; - uint16_t crc16_result; - - lprintf ("decode data %d bytes of type %08x, pts=%"PRId64"\n", - buf->size, buf->type, buf->pts); - lprintf ("decode data decoder_info=%d, %d\n",buf->decoder_info[1],buf->decoder_info[2]); - - if (buf->decoder_flags & BUF_FLAG_HEADER) - return; - - /* swap byte pairs if this is RealAudio DNET data */ - if (buf->type == BUF_AUDIO_DNET) { - - lprintf ("byte-swapping dnet\n"); - - while (current != end) { - byte = *current++; - *(current - 1) = *current; - *current++ = byte; - } - - /* reset */ - current = buf->content; - end = buf->content + buf->size; - } - - /* A52 packs come from the DVD in blocks of about 2048 bytes. - * Only 1 PTS values can be assigned to each block. - * An A52 frame is about 1700 bytes long. - * So, a single A52 packs can contain 2 A52 frames (or the beginning of an A52 frame at least). - * If we have a PTS value, which A52 frame does it apply to? The A52 pack tells us that. - * So, the info about which A52 frame the PTS applies to is contained in decoder_info sent from the demuxer. - * - * The PTS value from the A52 pack (DVD sector) can only be applied at the start of an A52 frame. - * We call the start of an A52 frame a frame header. - * So, if a A52 pack has 2 "Number of frame headers" is means that the A52 pack contains 2 A52 frame headers. - * The "First access unit" then tells us which A52 frame the PTS value applies to. - * - * Take the following example: - - * PACK1: PTS = 10. Contains the entire A52 frame1, followed by the beginning of the frame2. PTS applies to frame1. - * PACK2: PTS = 1000, Contains the rest of frame2, and the whole of frame3. and the start of frame4. PTS applies to frame4. - * PACK3: PTS = 0 (none), Contains the rest of frame4. - * - * Output should be: - - * frame1, PTS=10 - * frame2, PTS=0 - * frame3, PTS=0 - * frame4, PTS=1000 - * - * So, we have to keep track of PTS values from previous A52 packs here, otherwise they get put on the wrong frame. - */ - - - /* FIXME: the code here does not match the explanation above */ - if (buf->pts) { - int32_t info; - info = buf->decoder_info[1]; - this->pts = buf->pts; - this->pts_list[this->pts_list_position]=buf->pts; - this->pts_list_position++; - if( this->pts_list_position > 3 ) - this->pts_list_position = 3; - if (info == 2) { - this->pts_list[this->pts_list_position]=0; - this->pts_list_position++; - if( this->pts_list_position > 3 ) - this->pts_list_position = 3; - } - } -#if 0 - for(n=0;n < buf->size;n++) { - if ((n % 32) == 0) printf("\n"); - printf("%x ", current[n]); - } - printf("\n"); -#endif - - lprintf ("processing...state %d\n", this->sync_state); - - while (current < end) { - switch (this->sync_state) { - case 0: /* Looking for sync header */ - this->syncword = (this->syncword << 8) | *current++; - if (this->syncword == 0x0b77) { - - this->frame_buffer[0] = 0x0b; - this->frame_buffer[1] = 0x77; - - this->sync_state = 1; - this->frame_ptr = this->frame_buffer+2; - } - break; - - case 1: /* Looking for enough bytes for sync_info. */ - sync_start = current - 1; - *this->frame_ptr++ = *current++; - if ((this->frame_ptr - this->frame_buffer) > 16) { - int a52_flags_old = this->a52_flags; - int a52_sample_rate_old = this->a52_sample_rate; - int a52_bit_rate_old = this->a52_bit_rate; - - this->frame_length = a52_syncinfo (this->frame_buffer, - &this->a52_flags, - &this->a52_sample_rate, - &this->a52_bit_rate); - - if (this->frame_length < 80) { /* Invalid a52 frame_length */ - this->syncword = 0; - current = sync_start; - this->sync_state = 0; - break; - } - - lprintf("Frame length = %d\n",this->frame_length); - - this->frame_todo = this->frame_length - 17; - this->sync_state = 2; - if (!_x_meta_info_get(this->stream, XINE_META_INFO_AUDIOCODEC) || - a52_flags_old != this->a52_flags || - a52_sample_rate_old != this->a52_sample_rate || - a52_bit_rate_old != this->a52_bit_rate) { - - switch (this->a52_flags & A52_CHANNEL_MASK) { - case A52_3F2R: - if (this->a52_flags & A52_LFE) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 5.1"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 5.0"); - break; - case A52_3F1R: - case A52_2F2R: - if (this->a52_flags & A52_LFE) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 4.1"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 4.0"); - break; - case A52_2F1R: - case A52_3F: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 3.0"); - break; - case A52_STEREO: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 2.0 (stereo)"); - break; - case A52_DOLBY: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 2.0 (dolby)"); - break; - case A52_MONO: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52 1.0"); - break; - default: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "A/52"); - break; - } - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->a52_bit_rate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->a52_sample_rate); - } - } - break; - - case 2: /* Filling frame_buffer with sync_info bytes */ - *this->frame_ptr++ = *current++; - this->frame_todo--; - if (this->frame_todo < 1) { - this->sync_state = 3; - } else break; - - case 3: /* Ready for decode */ - crc16 = (uint16_t) ((this->frame_buffer[2] << 8) | this->frame_buffer[3]) ; - crc16_result = crc16_block(&this->frame_buffer[2], this->frame_length - 2) ; /* frame_length */ - if (crc16_result != 0) { /* CRC16 failed */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52:a52 frame failed crc16 checksum.\n"); - current = sync_start; - this->pts = 0; - this->syncword = 0; - this->sync_state = 0; - break; - } -#if 0 - a52dec_decode_frame (this, this->pts_list[0], buf->decoder_flags & BUF_FLAG_PREVIEW); -#else - a52dec_decode_frame (this, this->pts, buf->decoder_flags & BUF_FLAG_PREVIEW); -#endif - for(n=0;n<4;n++) { - this->pts_list[n] = this->pts_list[n+1]; - } - this->pts_list_position--; - if( this->pts_list_position < 0 ) - this->pts_list_position = 0; -#if 0 - printf("liba52: pts_list = %lld, %lld, %lld\n", - this->pts_list[0], - this->pts_list[1], - this->pts_list[2]); -#endif - case 4: /* Clear up ready for next frame */ - this->pts = 0; - this->syncword = 0; - this->sync_state = 0; - break; - default: /* No come here */ - break; - } - } - -#ifdef DEBUG_A52 - write (a52file, this->frame_buffer, this->frame_length); -#endif -} - -static void a52dec_dispose (audio_decoder_t *this_gen) { - - a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - this->output_open = 0; - - a52_free(this->a52_state); - this->a52_state = NULL; - -#ifdef DEBUG_A52 - close (a52file); -#endif - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - a52dec_decoder_t *this ; - - lprintf ("open_plugin called\n"); - - this = (a52dec_decoder_t *) xine_xmalloc (sizeof (a52dec_decoder_t)); - - this->audio_decoder.decode_data = a52dec_decode_data; - this->audio_decoder.reset = a52dec_reset; - this->audio_decoder.discontinuity = a52dec_discontinuity; - this->audio_decoder.dispose = a52dec_dispose; - this->stream = stream; - this->class = (a52dec_class_t *) class_gen; - - /* int i; */ - - this->audio_caps = stream->audio_out->get_capabilities(stream->audio_out); - this->syncword = 0; - this->sync_state = 0; - this->output_open = 0; - this->pts = 0; - this->pts_list[0] = 0; - this->pts_list_position = 0; - - if( !this->a52_state ) - this->a52_state = a52_init (xine_mm_accel()); - - /* - * find out if this driver supports a52 output - * or, if not, how many channels we've got - */ - - if (this->audio_caps & AO_CAP_MODE_A52) - this->bypass_mode = 1; - else { - this->bypass_mode = 0; - - this->a52_flags_map[A52_MONO] = A52_MONO; - this->a52_flags_map[A52_STEREO] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - this->a52_flags_map[A52_3F] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - this->a52_flags_map[A52_2F1R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - this->a52_flags_map[A52_3F1R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - this->a52_flags_map[A52_2F2R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - this->a52_flags_map[A52_3F2R] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - this->a52_flags_map[A52_DOLBY] = ((this->class->enable_surround_downmix ? A52_DOLBY : A52_STEREO)); - - this->ao_flags_map[A52_MONO] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_STEREO] = AO_CAP_MODE_STEREO; - this->ao_flags_map[A52_3F] = AO_CAP_MODE_STEREO; - this->ao_flags_map[A52_2F1R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[A52_3F1R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[A52_DOLBY] = AO_CAP_MODE_STEREO; - - /* find best mode */ - if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { - - this->a52_flags_map[A52_2F2R] = A52_2F2R; - this->a52_flags_map[A52_3F2R] = A52_3F2R | A52_LFE; - this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_5CHANNEL; - - } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { - - this->a52_flags_map[A52_2F2R] = A52_2F2R; - this->a52_flags_map[A52_3F2R] = A52_3F2R; - this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_5CHANNEL; - - } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { - - this->a52_flags_map[A52_2F2R] = A52_2F2R; - this->a52_flags_map[A52_3F2R] = A52_2F2R | A52_LFE; - this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_4CHANNEL; - - } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) { - - this->a52_flags_map[A52_2F2R] = A52_2F2R; - this->a52_flags_map[A52_3F2R] = A52_2F2R; - - this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_4CHANNEL; - - /* else if (this->audio_caps & AO_CAP_MODE_STEREO) - defaults are ok */ - } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) { - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("HELP! a mono-only audio driver?!\n")); - - this->a52_flags_map[A52_MONO] = A52_MONO; - this->a52_flags_map[A52_STEREO] = A52_MONO; - this->a52_flags_map[A52_3F] = A52_MONO; - this->a52_flags_map[A52_2F1R] = A52_MONO; - this->a52_flags_map[A52_3F1R] = A52_MONO; - this->a52_flags_map[A52_2F2R] = A52_MONO; - this->a52_flags_map[A52_3F2R] = A52_MONO; - this->a52_flags_map[A52_DOLBY] = A52_MONO; - - this->ao_flags_map[A52_MONO] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_STEREO] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_3F] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_2F1R] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_3F1R] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_MONO; - this->ao_flags_map[A52_DOLBY] = AO_CAP_MODE_MONO; - } - } - - /* - for (i = 0; i<8; i++) - this->a52_flags_map[i] |= A52_ADJUST_LEVEL; - */ -#ifdef DEBUG_A52 - a52file = open ("test.a52", O_CREAT | O_WRONLY | O_TRUNC, 0644); -#endif - return &this->audio_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - a52dec_class_t *this; - config_values_t *cfg; - - this = (a52dec_class_t *) xine_xmalloc (sizeof (a52dec_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "a/52dec"; - this->decoder_class.description = N_("liba52 based a52 audio decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - cfg = this->config = xine->config; - - this->a52_level = (float) cfg->register_range (cfg, "audio.a52.level", 100, - 0, 200, - _("A/52 volume"), - _("With A/52 audio, you can modify the volume " - "at the decoder level. This has the advantage " - "of the audio being already decoded for the " - "specified volume, so later operations like " - "channel downmixing will work on an audio stream " - "of the given volume."), - 10, a52_level_change_cb, this) / 100.0; - this->disable_dynrng_compress = !cfg->register_bool (cfg, "audio.a52.dynamic_range", 0, - _("use A/52 dynamic range compression"), - _("Dynamic range compression limits the dynamic " - "range of the audio. This means making the loud " - "sounds softer, and the soft sounds louder, so you can " - "more easily listen to the audio in a noisy " - "environment without disturbing anyone."), - 0, dynrng_compress_change_cb, this); - this->enable_surround_downmix = cfg->register_bool (cfg, "audio.a52.surround_downmix", 0, - _("downmix audio to 2 channel surround stereo"), - _("When you want to listen to multichannel surround " - "sound, but you have only two speakers or a " - "surround decoder or amplifier which does some " - "sort of matrix surround decoding like prologic, " - "you should enable this option so that the " - "additional channels are mixed into the stereo " - "signal."), - 0, surround_downmix_change_cb, this); - lprintf ("init_plugin called\n"); - return this; -} - -static void a52_level_change_cb(void *this_gen, xine_cfg_entry_t *entry) -{ - ((a52dec_class_t *)this_gen)->a52_level = entry->num_value / 100.0; -} - -static void dynrng_compress_change_cb(void *this_gen, xine_cfg_entry_t *entry) -{ - ((a52dec_class_t *)this_gen)->disable_dynrng_compress = !entry->num_value; -} - -static void surround_downmix_change_cb(void *this_gen, xine_cfg_entry_t *entry) -{ - ((a52dec_class_t *)this_gen)->enable_surround_downmix = entry->num_value; -} - - -static uint32_t audio_types[] = { - BUF_AUDIO_A52, - BUF_AUDIO_DNET, - 0 - }; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "a/52", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_dts_decoder.c b/src/libxineadec/xine_dts_decoder.c deleted file mode 100644 index 9d2fc5e93..000000000 --- a/src/libxineadec/xine_dts_decoder.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (C) 2000-2007 the xine project - * - * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -/** - * @file - * @brief DTS decoder for xine - * - * @author Joachim Koenig (2001-09-04) - * @author James Courtier-Dutton (2001-12-09) - */ - -#ifndef __sun -/* required for swab() */ -#define _XOPEN_SOURCE 500 -#endif -/* avoid compiler warnings */ -#define _BSD_SOURCE 1 - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "libdts" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include - -#include "bswap.h" - -#include - -#define MAX_AC5_FRAME 4096 - -typedef struct { - audio_decoder_class_t decoder_class; -} dts_class_t; - -typedef struct { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - audio_decoder_class_t *class; - - dts_state_t *dts_state; - int64_t pts; - - int audio_caps; - int sync_state; - int ac5_length, ac5_pcm_length, frame_todo; - uint32_t syncdword; - uint8_t frame_buffer[MAX_AC5_FRAME]; - uint8_t *frame_ptr; - - int output_open; - - int bypass_mode; - int dts_flags; - int dts_sample_rate; - int dts_bit_rate; - int dts_flags_map[11]; /* Convert from stream dts_flags to the dts_flags we want from the dts downmixer */ - int ao_flags_map[11]; /* Convert from the xine AO_CAP's to dts_flags. */ - int have_lfe; - - -} dts_decoder_t; - -static void dts_reset (audio_decoder_t *const this_gen) { -} - -static void dts_discontinuity (audio_decoder_t *const this_gen) { -} - -/** - * @brief Convert a array of floating point samples into 16-bit signed integer samples - * @param f Floating point samples array (origin) - * @param s16 16-bit signed integer samples array (destination) - * @param num_channels Number of channels present in the stream - * - * @todo This same work is being done in many decoders to adapt the output of - * the decoder to what the audio output can actually use, this should be - * done by the audio_output loop, not by the decoders. - * @note This is subtly different from the function with the same name in xine_musepack_decoder.c - */ -static inline void float_to_int (const float *const _f, int16_t *const s16, const int num_channels) { - const int endidx = 256 * num_channels; - int i, j; - - for (i = 0, j = 0; j < endidx; i++, j += num_channels) { - const float f = _f[i] * 32767; - if (f > INT16_MAX) - s16[j] = INT16_MAX; - else if (f < INT16_MIN) - s16[j] = INT16_MIN; - else - s16[j] = f; - /* printf("samples[%d] = %f, %d\n", i, _f[i], s16[num_channels*i]); */ - } -} - -static inline void mute_channel (int16_t *const s16, const int num_channels) { - const int endidx = 256 * num_channels; - int i; - - for (i = 0; i < endidx; i += num_channels) - s16[i] = 0; -} - -static void dts_decode_frame (dts_decoder_t *this, const int64_t pts, const int preview_mode) { - - audio_buffer_t *audio_buffer; - uint32_t ac5_spdif_type=0; - int output_mode = AO_CAP_MODE_STEREO; - uint8_t *data_out; - uint8_t *const data_in = this->frame_buffer; - - lprintf("decode_frame\n"); - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - audio_buffer->vpts = pts; - - if(this->bypass_mode) { - /* SPDIF digital output */ - if (!this->output_open) { - this->output_open = ((this->stream->audio_out->open) (this->stream->audio_out, this->stream, - 16, this->dts_sample_rate, - AO_CAP_MODE_AC5)); - } - - if (!this->output_open) - return; - - data_out=(uint8_t *) audio_buffer->mem; - if (this->ac5_length > 8191) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: ac5_length too long\n"); - this->ac5_pcm_length = 0; - } - - switch (this->ac5_pcm_length) { - case 512: - ac5_spdif_type = 0x0b; /* DTS-1 (512-sample bursts) */ - break; - case 1024: - ac5_spdif_type = 0x0c; /* DTS-1 (1024-sample bursts) */ - break; - case 2048: - ac5_spdif_type = 0x0d; /* DTS-1 (2048-sample bursts) */ - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libdts: DTS %i-sample bursts not supported\n", this->ac5_pcm_length); - return; - } - -#ifdef LOG_DEBUG - { - int i; - printf("libdts: DTS frame type=%d\n",data_in[4] >> 7); - printf("libdts: DTS deficit frame count=%d\n",(data_in[4] & 0x7f) >> 2); - printf("libdts: DTS AC5 PCM samples=%d\n",ac5_pcm_samples); - printf("libdts: DTS AC5 length=%d\n",this->ac5_length); - printf("libdts: DTS AC5 bitrate=%d\n",((data_in[8] & 0x03) << 4) | (data_in[8] >> 4)); - printf("libdts: DTS AC5 spdif type=%d\n", ac5_spdif_type); - - printf("libdts: "); - for(i=2000;i<2048;i++) { - printf("%02x ",data_in[i]); - } - printf("\n"); - } -#endif - - lprintf("length=%d pts=%"PRId64"\n",this->ac5_pcm_length,audio_buffer->vpts); - - audio_buffer->num_frames = this->ac5_pcm_length; - - data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */ - data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */ - data_out[4] = ac5_spdif_type; /* DTS data */ - data_out[5] = 0; /* Unknown */ - data_out[6] = (this->ac5_length << 3) & 0xff; /* ac5_length * 8 */ - data_out[7] = ((this->ac5_length ) >> 5) & 0xff; - - if( this->ac5_pcm_length ) { - if( this->ac5_pcm_length % 2) { - swab(data_in, &data_out[8], this->ac5_length ); - } else { - swab(data_in, &data_out[8], this->ac5_length + 1); - } - } - } else { - /* Software decode */ - int i, dts_output_flags; - int16_t *const int_samples = audio_buffer->mem; - int number_of_dts_blocks; - - level_t level = 1.0; - sample_t *samples; - - dts_output_flags = this->dts_flags_map[this->dts_flags & DTS_CHANNEL_MASK]; - - if(dts_frame(this->dts_state, data_in, &dts_output_flags, &level, 0)) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: dts_frame error\n"); - return; - } - - this->have_lfe = dts_output_flags & DTS_LFE; - if (this->have_lfe) - if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { - output_mode = AO_CAP_MODE_5_1CHANNEL; - } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { - output_mode = AO_CAP_MODE_4_1CHANNEL; - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: WHAT DO I DO!!!\n"); - output_mode = this->ao_flags_map[dts_output_flags & DTS_CHANNEL_MASK]; - } - else - output_mode = this->ao_flags_map[dts_output_flags & DTS_CHANNEL_MASK]; - - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, - 16, this->dts_sample_rate, - output_mode); - } - - if (!this->output_open) - return; - number_of_dts_blocks = dts_blocks_num (this->dts_state); - audio_buffer->num_frames = 256*number_of_dts_blocks; - for(i = 0; i < number_of_dts_blocks; i++) { - if(dts_block(this->dts_state)) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libdts: dts_block error on audio channel %d\n", i); - audio_buffer->num_frames = 0; - break; - } - - samples = dts_samples(this->dts_state); - switch (output_mode) { - case AO_CAP_MODE_MONO: - float_to_int (&samples[0], int_samples+(i*256), 1); - break; - case AO_CAP_MODE_STEREO: - /* Tested, working. */ - float_to_int (&samples[0*256], int_samples+(i*256*2), 2); /* L */ - float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2); /* R */ - break; - case AO_CAP_MODE_4CHANNEL: - /* Tested, working */ - float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */ - float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */ - float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */ - float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */ - break; - case AO_CAP_MODE_4_1CHANNEL: - /* Tested, working */ - float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ - float_to_int (&samples[1*256], int_samples+(i*256*6)+1, 6); /* R */ - float_to_int (&samples[2*256], int_samples+(i*256*6)+2, 6); /* RL */ - float_to_int (&samples[3*256], int_samples+(i*256*6)+3, 6); /* RR */ - float_to_int (&samples[4*256], int_samples+(i*256*6)+5, 6); /* LFE */ - mute_channel ( int_samples+(i*256*6)+4, 6); /* C */ - break; - case AO_CAP_MODE_5CHANNEL: - /* Tested, working */ - float_to_int (&samples[0*256], int_samples+(i*256*6)+4, 6); /* C */ - float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ - float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ - float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ - float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ - mute_channel ( int_samples+(i*256*6)+5, 6); /* LFE */ - break; - case AO_CAP_MODE_5_1CHANNEL: - float_to_int (&samples[0*256], int_samples+(i*256*6)+4, 6); /* C */ - float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ - float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ - float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ - float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ - float_to_int (&samples[5*256], int_samples+(i*256*6)+5, 6); /* LFE */ /* Not working yet */ - break; - default: - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: help - unsupported mode %08x\n", output_mode); - } - } - } - - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - -} - -static void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - dts_decoder_t *const this = (dts_decoder_t *) this_gen; - uint8_t *current = (uint8_t *)buf->content; - uint8_t *sync_start=current + 1; - uint8_t *const end = buf->content + buf->size; - - lprintf("decode_data\n"); - - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - if (buf->decoder_flags & BUF_FLAG_STDHEADER) - return; - - lprintf ("processing...state %d\n", this->sync_state); - - while (current < end) { - switch (this->sync_state) { - case 0: /* Looking for sync header */ - this->syncdword = (this->syncdword << 8) | *current++; -/* - if ((this->syncdword == 0xff1f00e8) || - (this->syncdword == 0x1fffe800) || - (this->syncdword == 0xfe7f0180) || - (this->syncdword == 0x7ffe8001) ) { -*/ - - if ((this->syncdword == 0x7ffe8001) || (this->syncdword == 0xff1f00e8)) { - const uint32_t be_syncdword = be2me_32(this->syncdword); - - lprintf ("sync found: syncdword=0x%x\n", this->syncdword); - - memcpy(this->frame_buffer, &be_syncdword, sizeof(be_syncdword)); - - this->sync_state = 1; - this->frame_ptr = this->frame_buffer+4; - this->pts = buf->pts; - } - break; - - case 1: /* Looking for enough bytes for sync_info. */ - sync_start = current - 1; - *this->frame_ptr++ = *current++; - if ((this->frame_ptr - this->frame_buffer) > 19) { - const int old_dts_flags = this->dts_flags; - const int old_dts_sample_rate = this->dts_sample_rate; - const int old_dts_bit_rate = this->dts_bit_rate; - - this->ac5_length = dts_syncinfo (this->dts_state, this->frame_buffer, - &this->dts_flags, - &this->dts_sample_rate, - &this->dts_bit_rate, &(this->ac5_pcm_length)); - lprintf("ac5_length=%d\n",this->ac5_length); - lprintf("dts_sample_rate=%d\n",this->dts_sample_rate); - - if ( (this->ac5_length < 80) || (this->ac5_length > MAX_AC5_FRAME) ) { /* Invalid dts ac5_pcm_length */ - this->syncdword = 0; - current = sync_start; - this->sync_state = 0; - break; - } - - lprintf("Frame length = %d\n",this->ac5_pcm_length); - - this->frame_todo = this->ac5_length - 20; - this->sync_state = 2; - if (!_x_meta_info_get(this->stream, XINE_META_INFO_AUDIOCODEC) || - old_dts_flags != this->dts_flags || - old_dts_sample_rate != this->dts_sample_rate || - old_dts_bit_rate != this->dts_bit_rate) { - - switch (this->dts_flags & DTS_CHANNEL_MASK) { - case DTS_3F2R: - if (this->dts_flags & DTS_LFE) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 5.1"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 5.0"); - break; - case DTS_3F1R: - case DTS_2F2R: - if (this->dts_flags & DTS_LFE) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 4.1"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 4.0"); - break; - case DTS_2F1R: - case DTS_3F: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 3.0"); - break; - case DTS_STEREO: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 2.0 (stereo)"); - break; - case DTS_MONO: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 1.0"); - break; - default: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS"); - break; - } - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->dts_bit_rate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->dts_sample_rate); - } - } - break; - - case 2: /* Filling frame_buffer with sync_info bytes */ - *this->frame_ptr++ = *current++; - this->frame_todo--; - if (this->frame_todo < 1) { - this->sync_state = 3; - } else break; - - case 3: /* Ready for decode */ -#if 0 - dtsdec_decode_frame (this, this->pts_list[0], buf->decoder_flags & BUF_FLAG_PREVIEW); -#else - dts_decode_frame (this, this->pts, buf->decoder_flags & BUF_FLAG_PREVIEW); -#endif - case 4: /* Clear up ready for next frame */ - this->pts = 0; - this->syncdword = 0; - this->sync_state = 0; - break; - default: /* No come here */ - break; - } - } -} - -static void dts_dispose (audio_decoder_t *this_gen) { - dts_decoder_t *const this = (dts_decoder_t *) this_gen; - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - free (this); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - dts_decoder_t *this ; - - lprintf("open_plugin\n"); - - this = (dts_decoder_t *) xine_xmalloc (sizeof (dts_decoder_t)); - - this->audio_decoder.decode_data = dts_decode_data; - this->audio_decoder.reset = dts_reset; - this->audio_decoder.discontinuity = dts_discontinuity; - this->audio_decoder.dispose = dts_dispose; - - this->dts_state = dts_init(0); - this->audio_caps = stream->audio_out->get_capabilities(stream->audio_out); - if(this->audio_caps & AO_CAP_MODE_AC5) - this->bypass_mode = 1; - else { - this->bypass_mode = 0; - /* FIXME: Leave "DOLBY pro logic" downmix out for now. */ - this->dts_flags_map[DTS_MONO] = DTS_MONO; - this->dts_flags_map[DTS_STEREO] = DTS_STEREO; - this->dts_flags_map[DTS_3F] = DTS_STEREO; - this->dts_flags_map[DTS_2F1R] = DTS_STEREO; - this->dts_flags_map[DTS_3F1R] = DTS_STEREO; - this->dts_flags_map[DTS_2F2R] = DTS_STEREO; - this->dts_flags_map[DTS_3F2R] = DTS_STEREO; - - this->ao_flags_map[DTS_MONO] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_STEREO] = AO_CAP_MODE_STEREO; - this->ao_flags_map[DTS_3F] = AO_CAP_MODE_STEREO; - this->ao_flags_map[DTS_2F1R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[DTS_3F1R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_STEREO; - this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_STEREO; - - /* find best mode */ - if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { - - this->dts_flags_map[DTS_2F2R] = DTS_2F2R; - this->dts_flags_map[DTS_3F2R] = DTS_3F2R | DTS_LFE; - this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_5CHANNEL; - - } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { - - this->dts_flags_map[DTS_2F2R] = DTS_2F2R; - this->dts_flags_map[DTS_3F2R] = DTS_3F2R; - this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_5CHANNEL; - - } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { - - this->dts_flags_map[DTS_2F2R] = DTS_2F2R; - this->dts_flags_map[DTS_3F2R] = DTS_2F2R | DTS_LFE; - this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_4CHANNEL; - - } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) { - - this->dts_flags_map[DTS_2F2R] = DTS_2F2R; - this->dts_flags_map[DTS_3F2R] = DTS_2F2R; - - this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; - this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_4CHANNEL; - - /* else if (this->audio_caps & AO_CAP_MODE_STEREO) - defaults are ok */ - } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) { - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("HELP! a mono-only audio driver?!\n")); - - this->dts_flags_map[DTS_MONO] = DTS_MONO; - this->dts_flags_map[DTS_STEREO] = DTS_MONO; - this->dts_flags_map[DTS_3F] = DTS_MONO; - this->dts_flags_map[DTS_2F1R] = DTS_MONO; - this->dts_flags_map[DTS_3F1R] = DTS_MONO; - this->dts_flags_map[DTS_2F2R] = DTS_MONO; - this->dts_flags_map[DTS_3F2R] = DTS_MONO; - - this->ao_flags_map[DTS_MONO] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_STEREO] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_3F] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_2F1R] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_3F1R] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_MONO; - this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_MONO; - } - } - this->stream = stream; - this->class = class_gen; - this->output_open = 0; - - return &this->audio_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - dts_class_t *this ; - - lprintf("init_plugin\n"); - - this = (dts_class_t *) xine_xmalloc (sizeof (dts_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "DTS"; - this->decoder_class.description = N_("DTS passthru audio format decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_DTS, 0 - }; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 16, "dts", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_faad_decoder.c b/src/libxineadec/xine_faad_decoder.c deleted file mode 100644 index 6b242005a..000000000 --- a/src/libxineadec/xine_faad_decoder.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) 2000-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "libfaad" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include -#ifdef HAVE_NEAACDEC_H -#include -#else -#include "common.h" -#include "structs.h" -#include "decoder.h" -#include "syntax.h" -#endif - -#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */ - -typedef struct { - audio_decoder_class_t decoder_class; -} faad_class_t; - -typedef struct faad_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - /* faad2 stuff */ - NeAACDecHandle faac_dec; - NeAACDecConfigurationPtr faac_cfg; - NeAACDecFrameInfo faac_finfo; - int faac_failed; - - int raw_mode; - - unsigned char *buf; - int size; - int rec_audio_src_size; - int max_audio_src_size; - int pts; - - unsigned char *dec_config; - int dec_config_size; - - unsigned long rate; - int bits_per_sample; - unsigned char num_channels; - int sbr; - - int output_open; - - unsigned long total_time; - unsigned long total_data; -} faad_decoder_t; - - -static void faad_reset (audio_decoder_t *this_gen) { - - faad_decoder_t *this = (faad_decoder_t *) this_gen; - this->size = 0; -} - -static void faad_meta_info_set ( faad_decoder_t *this ) { - switch (this->num_channels) { - case 1: - if (this->faac_finfo.sbr == SBR_UPSAMPLED) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "HE-AAC 1.0 (libfaad)"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "AAC 1.0 (libfaad)"); - break; - case 2: - /* check if this is downmixed 5.1 */ - if (!this->faac_cfg || !this->faac_cfg->downMatrix) { - if (this->faac_finfo.sbr == SBR_UPSAMPLED) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "HE-AAC 2.0 (libfaad)"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "AAC 2.0 (libfaad)"); - break; - } - case 6: - if (this->faac_finfo.sbr == SBR_UPSAMPLED) - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "HE-AAC 5.1 (libfaad)"); - else - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "AAC 5.1 (libfaad)"); - break; - } -} - -static int faad_open_dec( faad_decoder_t *this ) { - int used; - - this->faac_dec = NeAACDecOpen(); - if( !this->faac_dec ) { - xprintf( this->stream->xine, XINE_VERBOSITY_LOG, - _("libfaad: libfaad NeAACDecOpen() failed.\n")); - this->faac_failed++; - } else { - if( this->dec_config ) { - used = NeAACDecInit2(this->faac_dec, this->dec_config, this->dec_config_size, - &this->rate, &this->num_channels); - - if( used < 0 ) { - xprintf( this->stream->xine, XINE_VERBOSITY_LOG, - _("libfaad: libfaad NeAACDecInit2 failed.\n")); - this->faac_failed++; - } else - lprintf( "NeAACDecInit2 returned rate=%"PRId32" channels=%d\n", - this->rate, this->num_channels ); - } else { - used = NeAACDecInit(this->faac_dec, this->buf, this->size, - &this->rate, &this->num_channels); - - if( used < 0 ) { - xprintf ( this->stream->xine, XINE_VERBOSITY_LOG, - _("libfaad: libfaad NeAACDecInit failed.\n")); - this->faac_failed++; - } else { - lprintf( "NeAACDecInit() returned rate=%"PRId32" channels=%d (used=%d)\n", - this->rate, this->num_channels, used); - - this->size -= used; - memmove( this->buf, &this->buf[used], this->size ); - } - } - } - - if( !this->bits_per_sample ) - this->bits_per_sample = 16; - - if( this->faac_failed ) { - if( this->faac_dec ) { - NeAACDecClose( this->faac_dec ); - this->faac_dec = NULL; - } - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - } else { - faad_meta_info_set(this); - } - - return this->faac_failed; -} - -static int faad_open_output( faad_decoder_t *this ) { - int ao_cap_mode; - - this->rec_audio_src_size = this->num_channels * FAAD_MIN_STREAMSIZE; - - switch( this->num_channels ) { - case 1: - ao_cap_mode=AO_CAP_MODE_MONO; - break; - case 6: - if(this->stream->audio_out->get_capabilities(this->stream->audio_out) & - AO_CAP_MODE_5_1CHANNEL) { - ao_cap_mode = AO_CAP_MODE_5_1CHANNEL; - break; - } else { - this->faac_cfg = NeAACDecGetCurrentConfiguration(this->faac_dec); - this->faac_cfg->downMatrix = 1; - NeAACDecSetConfiguration(this->faac_dec, this->faac_cfg); - this->num_channels = 2; - } - case 2: - ao_cap_mode=AO_CAP_MODE_STEREO; - break; - default: - return 0; - } - - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, - this->bits_per_sample, - this->rate, - ao_cap_mode) ; - return this->output_open; -} - -static void faad_decode_audio ( faad_decoder_t *this, int end_frame ) { - int used, decoded, outsize; - uint8_t *sample_buffer; - uint8_t *inbuf; - audio_buffer_t *audio_buffer; - int sample_size = this->size; - - if( !this->faac_dec ) - return; - - inbuf = this->buf; - while( (!this->raw_mode && end_frame && this->size >= 10) || - (this->raw_mode && this->size >= this->rec_audio_src_size) ) { - - sample_buffer = NeAACDecDecode(this->faac_dec, - &this->faac_finfo, inbuf, sample_size); - - if( !sample_buffer ) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libfaad: %s\n", NeAACDecGetErrorMessage(this->faac_finfo.error)); - used = 1; - } else { - used = this->faac_finfo.bytesconsumed; - - /* raw AAC parameters might only be known after decoding the first frame */ - if( !this->dec_config && - (this->num_channels != this->faac_finfo.channels || - this->rate != this->faac_finfo.samplerate) ) { - - this->num_channels = this->faac_finfo.channels; - this->rate = this->faac_finfo.samplerate; - - lprintf("NeAACDecDecode() returned rate=%"PRId32" channels=%d used=%d\n", - this->rate, this->num_channels, used); - - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - faad_open_output( this ); - - faad_meta_info_set( this ); - } - - /* faad doesn't tell us about sbr until after the first frame */ - if (this->sbr != this->faac_finfo.sbr) { - this->sbr = this->faac_finfo.sbr; - faad_meta_info_set( this ); - } - - /* estimate bitrate */ - this->total_time += (1000*this->faac_finfo.samples/(this->rate*this->num_channels)); - this->total_data += 8*used; - - if ((this->total_time > LONG_MAX) || (this->total_data > LONG_MAX)) { - this->total_time >>= 2; - this->total_data >>= 2; - } - - if (this->total_time) - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, - 1000*(this->total_data/this->total_time)); - - decoded = this->faac_finfo.samples * 2; /* 1 sample = 2 bytes */ - - lprintf("decoded %d/%d output %ld\n", - used, this->size, this->faac_finfo.samples ); - - while( decoded ) { - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - if( decoded < audio_buffer->mem_size ) - outsize = decoded; - else - outsize = audio_buffer->mem_size; - - xine_fast_memcpy( audio_buffer->mem, sample_buffer, outsize ); - - audio_buffer->num_frames = outsize / (this->num_channels*2); - audio_buffer->vpts = this->pts; - - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - this->pts = 0; - decoded -= outsize; - sample_buffer += outsize; - } - } - - if(used >= this->size){ - this->size = 0; - } else { - this->size -= used; - inbuf += used; - } - - if( !this->raw_mode ) - this->size = 0; - } - - if( this->size ) - memmove( this->buf, inbuf, this->size); - -} - -static void faad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - faad_decoder_t *this = (faad_decoder_t *) this_gen; - - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - /* store config information from ESDS mp4/qt atom */ - if( !this->faac_dec && (buf->decoder_flags & BUF_FLAG_SPECIAL) && - buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG ) { - - this->dec_config = xine_xmalloc(buf->decoder_info[2]); - this->dec_config_size = buf->decoder_info[2]; - memcpy(this->dec_config, buf->decoder_info_ptr[2], buf->decoder_info[2]); - - if( faad_open_dec(this) ) - return; - - this->raw_mode = 0; - } - - /* get audio parameters from file header - (may be overwritten by libfaad returned parameters) */ - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - this->rate=buf->decoder_info[1]; - this->bits_per_sample=buf->decoder_info[2] ; - this->num_channels=buf->decoder_info[3] ; - - if( buf->size > sizeof(xine_waveformatex) ) { - xine_waveformatex *wavex = (xine_waveformatex *) buf->content; - - if( wavex->cbSize > 0 ) { - this->dec_config = xine_xmalloc(wavex->cbSize); - this->dec_config_size = wavex->cbSize; - memcpy(this->dec_config, buf->content + sizeof(xine_waveformatex), - wavex->cbSize); - - if( faad_open_dec(this) ) - return; - - this->raw_mode = 0; - } - } - } else { - - lprintf ("decoding %d data bytes...\n", buf->size); - - if( (int)buf->size <= 0 || this->faac_failed ) - return; - - if( !this->size ) - this->pts = buf->pts; - - if( this->size + buf->size > this->max_audio_src_size ) { - this->max_audio_src_size = this->size + 2 * buf->size; - this->buf = realloc( this->buf, this->max_audio_src_size ); - } - - memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if( !this->faac_dec && faad_open_dec(this) ) - return; - - /* open audio device as needed */ - if (!this->output_open) { - faad_open_output( this ); - } - - faad_decode_audio(this, buf->decoder_flags & BUF_FLAG_FRAME_END ); - } -} - -static void faad_discontinuity (audio_decoder_t *this_gen) { -} - -static void faad_dispose (audio_decoder_t *this_gen) { - - faad_decoder_t *this = (faad_decoder_t *) this_gen; - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - if( this->buf ) - free(this->buf); - this->buf = NULL; - this->size = 0; - this->max_audio_src_size = 0; - - if( this->dec_config ) - free(this->dec_config); - this->dec_config = NULL; - this->dec_config_size = 0; - - if( this->faac_dec ) - NeAACDecClose(this->faac_dec); - this->faac_dec = NULL; - this->faac_failed = 0; - - free (this); -} - - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - faad_decoder_t *this ; - - this = (faad_decoder_t *) xine_xmalloc (sizeof (faad_decoder_t)); - - this->audio_decoder.decode_data = faad_decode_data; - this->audio_decoder.reset = faad_reset; - this->audio_decoder.discontinuity = faad_discontinuity; - this->audio_decoder.dispose = faad_dispose; - - this->stream = stream; - this->output_open = 0; - this->raw_mode = 1; - this->faac_dec = NULL; - this->faac_failed = 0; - this->buf = NULL; - this->size = 0; - this->max_audio_src_size = 0; - this->dec_config = NULL; - this->dec_config_size = 0; - this->total_time = 0; - this->total_data = 0; - - this->rate = 0; - - return &this->audio_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - faad_class_t *this ; - - this = (faad_class_t *) xine_xmalloc (sizeof (faad_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "FAAD"; - this->decoder_class.description = N_("Freeware Advanced Audio Decoder"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_AAC, 0 - }; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 16, "faad", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c deleted file mode 100644 index 51d2e3137..000000000 --- a/src/libxineadec/xine_lpcm_decoder.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -/** - * @file - * @author James Courtier-Dutton - * - * @date 2001-08-31 Added LPCM rate sensing - */ - -#ifndef __sun -#define _XOPEN_SOURCE 500 -#endif -/* avoid compiler warnings */ -#define _BSD_SOURCE 1 - -#include -#include -#include -#include -#include -#include -#include /* ntohs */ - -#include -#include -#include - -#ifdef WIN32 -#include -/*#include */ /* htons */ -#endif - -typedef struct { - audio_decoder_class_t decoder_class; -} lpcm_class_t; - -typedef struct lpcm_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - uint32_t rate; - uint32_t bits_per_sample; - uint32_t number_of_channels; - uint32_t ao_cap_mode; - - int output_open; - int cpu_be; /**< TRUE, if we're a Big endian CPU */ -} lpcm_decoder_t; - -static void lpcm_reset (audio_decoder_t *this_gen) { - - /* lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; */ - -} - -static void lpcm_discontinuity (audio_decoder_t *this_gen) { -} - -static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; - int16_t *sample_buffer=(int16_t *)buf->content; - int stream_be; - audio_buffer_t *audio_buffer; - int format_changed = 0; - - /* Drop preview data */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - /* get config byte from mpeg2 stream */ - if ( (buf->decoder_flags & BUF_FLAG_SPECIAL) && - buf->decoder_info[1] == BUF_SPECIAL_LPCM_CONFIG ) { - unsigned int bits_per_sample = 16; - unsigned int sample_rate = 0; - unsigned int num_channels; - - num_channels = (buf->decoder_info[2] & 0x7) + 1; - switch ((buf->decoder_info[2]>>4) & 3) { - case 0: sample_rate = 48000; break; - case 1: sample_rate = 96000; break; - case 2: sample_rate = 44100; break; - case 3: sample_rate = 32000; break; - } - switch ((buf->decoder_info[2]>>6) & 3) { - case 0: bits_per_sample = 16; break; - case 1: bits_per_sample = 20; break; - case 2: bits_per_sample = 24; break; - } - - if( this->bits_per_sample != bits_per_sample || - this->number_of_channels != num_channels || - this->rate != sample_rate || - !this->output_open ) { - this->bits_per_sample = bits_per_sample; - this->number_of_channels = num_channels; - this->rate = sample_rate; - format_changed++; - } - } - - if( buf->decoder_flags & BUF_FLAG_STDHEADER ) { - this->rate=buf->decoder_info[1]; - this->bits_per_sample=buf->decoder_info[2] ; - this->number_of_channels=buf->decoder_info[3] ; - format_changed++; - } - - /* - * (re-)open output device - */ - if ( format_changed ) { - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - this->ao_cap_mode=_x_ao_channels2mode(this->number_of_channels); - - /* force 24-bit samples into 16 bits for now */ - if (this->bits_per_sample == 24) - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, - 16, - this->rate, - this->ao_cap_mode) ; - else - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, - this->bits_per_sample, - this->rate, - this->ao_cap_mode) ; - - /* stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Linear PCM"); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, - this->bits_per_sample * this->rate * this->number_of_channels); - } - - if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) - return; - - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - /* Swap LPCM samples into native byte order, if necessary */ - buf->type &= 0xffff0000; - stream_be = ( buf->type == BUF_AUDIO_LPCM_BE ); - - if( this->bits_per_sample == 16 ){ - if (stream_be != this->cpu_be) - swab (sample_buffer, audio_buffer->mem, buf->size); - else - memcpy (audio_buffer->mem, sample_buffer, buf->size); - } - else if( this->bits_per_sample == 20 ) { - uint8_t *s = (uint8_t *)sample_buffer; - uint8_t *d = (uint8_t *)audio_buffer->mem; - int n = buf->size; - - if (stream_be != this->cpu_be) { - while( n >= 0 ) { - swab( s, d, 8 ); - s += 10; - d += 8; - n -= 10; - } - } else { - while( n >= 0 ) { - memcpy( d, s, 8 ); - s += 10; - d += 8; - n -= 10; - } - } - } else if( this->bits_per_sample == 24 ) { - uint8_t *s = (uint8_t *)sample_buffer; - uint8_t *d = (uint8_t *)audio_buffer->mem; - int n = buf->size; - - while (n >= 0) { - if ( stream_be ) { - *d++ = s[0]; - *d++ = s[1]; - } else { - *d++ = s[1]; - *d++ = s[2]; - } - - s += 3; - n -= 3; - } - } else { - memcpy (audio_buffer->mem, sample_buffer, buf->size); - } - - audio_buffer->vpts = buf->pts; - audio_buffer->num_frames = (((buf->size*8)/this->number_of_channels)/this->bits_per_sample); - - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - -} - -static void lpcm_dispose (audio_decoder_t *this_gen) { - lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - lpcm_decoder_t *this ; - - this = (lpcm_decoder_t *) xine_xmalloc (sizeof (lpcm_decoder_t)); - - this->audio_decoder.decode_data = lpcm_decode_data; - this->audio_decoder.reset = lpcm_reset; - this->audio_decoder.discontinuity = lpcm_discontinuity; - this->audio_decoder.dispose = lpcm_dispose; - - this->output_open = 0; - this->rate = 0; - this->bits_per_sample=0; - this->number_of_channels=0; - this->ao_cap_mode=0; - this->stream = stream; - - this->cpu_be = ( htons(1) == 1 ); - - return &this->audio_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - lpcm_class_t *this ; - - this = (lpcm_class_t *) xine_xmalloc (sizeof (lpcm_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "Linear PCM"; - this->decoder_class.description = N_("Linear PCM audio decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_LPCM_BE, BUF_AUDIO_LPCM_LE, 0 -}; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 16, "pcm", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_mad_decoder.c b/src/libxineadec/xine_mad_decoder.c deleted file mode 100644 index 21e5bf46b..000000000 --- a/src/libxineadec/xine_mad_decoder.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stuff needed to turn libmad into a xine decoder plugin - */ - -#include -#include -#include - -#ifdef HAVE_MAD_H -#include -#endif - -#define LOG_MODULE "mad_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include - -#ifdef HAVE_MAD_H -# include -#else -# include "frame.h" -# include "synth.h" -#endif - -#define INPUT_BUF_SIZE 16384 - -typedef struct { - audio_decoder_class_t decoder_class; -} mad_class_t; - -typedef struct mad_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *xstream; - - int64_t pts; - - struct mad_synth synth; - struct mad_stream stream; - struct mad_frame frame; - - int output_sampling_rate; - int output_open; - int output_mode; - - uint8_t buffer[INPUT_BUF_SIZE]; - int bytes_in_buffer; - int preview_mode; - -} mad_decoder_t; - -static void mad_reset (audio_decoder_t *this_gen) { - - mad_decoder_t *this = (mad_decoder_t *) this_gen; - - mad_synth_finish (&this->synth); - mad_frame_finish (&this->frame); - mad_stream_finish(&this->stream); - - this->pts = 0; - this->bytes_in_buffer = 0; - this->preview_mode = 0; - - mad_synth_init (&this->synth); - mad_stream_init (&this->stream); - this->stream.options = MAD_OPTION_IGNORECRC; - mad_frame_init (&this->frame); -} - - -static void mad_discontinuity (audio_decoder_t *this_gen) { - - mad_decoder_t *this = (mad_decoder_t *) this_gen; - - this->pts = 0; -} - -/* utility to scale and round samples to 16 bits */ - -static inline -signed int scale(mad_fixed_t sample) -{ - /* round */ - sample += (1L << (MAD_F_FRACBITS - 16)); - - /* clip */ - if (sample >= MAD_F_ONE) - sample = MAD_F_ONE - 1; - else if (sample < -MAD_F_ONE) - sample = -MAD_F_ONE; - - /* quantize */ - return sample >> (MAD_F_FRACBITS + 1 - 16); -} - -/* -static int head_check(mad_decoder_t *this) { - - if( (this->header & 0xffe00000) != 0xffe00000) - return 0; - if(!((this->header>>17)&3)) - return 0; - if( ((this->header>>12)&0xf) == 0xf) - return 0; - if( ((this->header>>10)&0x3) == 0x3 ) - return 0; - return 1; -} -*/ - -static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - mad_decoder_t *this = (mad_decoder_t *) this_gen; - - lprintf ("decode data, decoder_flags: %d\n", buf->decoder_flags); - - if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) { - xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG, - "libmad: ALERT input buffer too small (%d bytes, %d avail)!\n", - buf->size, INPUT_BUF_SIZE-this->bytes_in_buffer); - buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer; - } - - if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) { - - /* reset decoder on leaving preview mode */ - if ((buf->decoder_flags & BUF_FLAG_PREVIEW) == 0) { - if (this->preview_mode) { - mad_reset (this_gen); - } - } else { - this->preview_mode = 1; - } - - xine_fast_memcpy (&this->buffer[this->bytes_in_buffer], - buf->content, buf->size); - this->bytes_in_buffer += buf->size; - - /* - printf ("libmad: decode data - doing it\n"); - */ - - mad_stream_buffer (&this->stream, this->buffer, - this->bytes_in_buffer); - - while (1) { - - if (mad_frame_decode (&this->frame, &this->stream) != 0) { - - if (this->stream.next_frame) { - int num_bytes = - this->buffer + this->bytes_in_buffer - this->stream.next_frame; - - /* printf("libmad: MAD_ERROR_BUFLEN\n"); */ - - memmove(this->buffer, this->stream.next_frame, num_bytes); - this->bytes_in_buffer = num_bytes; - } - - switch (this->stream.error) { - - case MAD_ERROR_BUFLEN: - return; - - default: - mad_stream_buffer (&this->stream, this->buffer, - this->bytes_in_buffer); - } - - } else { - int mode = (this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? AO_CAP_MODE_MONO : AO_CAP_MODE_STEREO; - - if (!this->output_open - || (this->output_sampling_rate != this->frame.header.samplerate) - || (this->output_mode != mode)) { - - lprintf ("audio sample rate %d mode %08x\n", this->frame.header.samplerate, mode); - - /* the mpeg audio demuxer can set audio bitrate */ - if (! _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE)) { - _x_stream_info_set(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE, - this->frame.header.bitrate); - } - - /* the mpeg audio demuxer can set this meta info */ - if (! _x_meta_info_get(this->xstream, XINE_META_INFO_AUDIOCODEC)) { - switch (this->frame.header.layer) { - case MAD_LAYER_I: - _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, - "MPEG audio layer 1 (lib: MAD)"); - break; - case MAD_LAYER_II: - _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, - "MPEG audio layer 2 (lib: MAD)"); - break; - case MAD_LAYER_III: - _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, - "MPEG audio layer 3 (lib: MAD)"); - break; - default: - _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, - "MPEG audio (lib: MAD)"); - } - } - - if (this->output_open) { - this->xstream->audio_out->close (this->xstream->audio_out, this->xstream); - this->output_open = 0; - } - if (!this->output_open) { - this->output_open = (this->xstream->audio_out->open) (this->xstream->audio_out, - this->xstream, 16, - this->frame.header.samplerate, - mode) ; - } - if (!this->output_open) { - return; - } - this->output_sampling_rate = this->frame.header.samplerate; - this->output_mode = mode; - } - - mad_synth_frame (&this->synth, &this->frame); - - if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) { - - unsigned int nchannels, nsamples; - mad_fixed_t const *left_ch, *right_ch; - struct mad_pcm *pcm = &this->synth.pcm; - audio_buffer_t *audio_buffer; - uint16_t *output; - - audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out); - output = audio_buffer->mem; - - nchannels = pcm->channels; - nsamples = pcm->length; - left_ch = pcm->samples[0]; - right_ch = pcm->samples[1]; - - while (nsamples--) { - /* output sample(s) in 16-bit signed little-endian PCM */ - - *output++ = scale(*left_ch++); - - if (nchannels == 2) - *output++ = scale(*right_ch++); - - } - - audio_buffer->num_frames = pcm->length; - audio_buffer->vpts = buf->pts; - - this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream); - - buf->pts = 0; - - } - - lprintf ("decode worked\n"); - } - } - - } -} - -static void mad_dispose (audio_decoder_t *this_gen) { - - mad_decoder_t *this = (mad_decoder_t *) this_gen; - - mad_synth_finish (&this->synth); - mad_frame_finish (&this->frame); - mad_stream_finish(&this->stream); - - if (this->output_open) { - this->xstream->audio_out->close (this->xstream->audio_out, this->xstream); - this->output_open = 0; - } - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - mad_decoder_t *this ; - - this = (mad_decoder_t *) xine_xmalloc (sizeof (mad_decoder_t)); - - this->audio_decoder.decode_data = mad_decode_data; - this->audio_decoder.reset = mad_reset; - this->audio_decoder.discontinuity = mad_discontinuity; - this->audio_decoder.dispose = mad_dispose; - - this->output_open = 0; - this->bytes_in_buffer = 0; - this->preview_mode = 0; - - this->xstream = stream; - - mad_synth_init (&this->synth); - mad_stream_init (&this->stream); - mad_frame_init (&this->frame); - - this->stream.options = MAD_OPTION_IGNORECRC; - - lprintf ("init\n"); - - return &this->audio_decoder; -} - -/* - * mad plugin class - */ -static void *init_plugin (xine_t *xine, void *data) { - - mad_class_t *this; - - this = (mad_class_t *) xine_xmalloc (sizeof (mad_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "mad"; - this->decoder_class.description = N_("libmad based mpeg audio layer 1/2/3 decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_MPEG, 0 -}; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 7 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 16, "mad", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_musepack_decoder.c b/src/libxineadec/xine_musepack_decoder.c deleted file mode 100644 index 268846a1a..000000000 --- a/src/libxineadec/xine_musepack_decoder.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -/** - * @file - * @brief xine interface to libmusepack/libmpcdec - * @author James Stembridge - * - * @todo Add support for 32-bit float samples. - * @todo Add support for seeking. - */ - -#include -#include -#include -#include -#include - -#define LOG_MODULE "mpc_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include - -#include - -#define MPC_DECODER_MEMSIZE 65536 -#define MPC_DECODER_MEMSIZE2 (MPC_DECODER_MEMSIZE/2) - -#define INIT_BUFSIZE (MPC_DECODER_MEMSIZE*2) - -typedef struct { - audio_decoder_class_t decoder_class; -} mpc_class_t; - -typedef struct mpc_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - int sample_rate; /* audio sample rate */ - int bits_per_sample; /* bits/sample, usually 8 or 16 */ - int channels; /* 1 or 2, usually */ - - int output_open; /* flag to indicate audio is ready */ - - unsigned char *buf; /* data accumulation buffer */ - unsigned int buf_max; /* maximum size of buf */ - unsigned int read; /* size of accum. data already read */ - unsigned int size; /* size of accumulated data in buf */ - - mpc_reader reader; - mpc_streaminfo streaminfo; - mpc_decoder decoder; - - int decoder_ok; - unsigned int current_frame; - - int32_t file_size; - -} mpc_decoder_t; - - -/************************************************************************** - * musepack specific functions - *************************************************************************/ - -/* Reads size bytes of data into buffer at ptr. */ -static int32_t mpc_reader_read(void *const data, void *const ptr, int size) { - mpc_decoder_t *const this = (mpc_decoder_t *) data; - - lprintf("mpc_reader_read: size=%d\n", size); - - /* Don't try to read more data than we have */ - if (size > (this->size - this->read)) - size = this->size - this->read; - - /* Copy the data */ - xine_fast_memcpy(ptr, &this->buf[this->read], size); - - /* Update our position in the data buffer */ - this->read += size; - - return size; -} - -/* Seeks to byte position offset. */ -static mpc_bool_t mpc_reader_seek(void *const data, const int32_t offset) { - mpc_decoder_t *const this = (mpc_decoder_t *) data; - - lprintf("mpc_reader_seek: offset=%d\n", offset); - - /* seek is only called when reading the header so we can assume - * that the buffer starts at the start of the file */ - this->read = offset; - - return TRUE; -} - -/* Returns the current byte offset in the stream. */ -static int32_t mpc_reader_tell(void *const data) { - lprintf("mpc_reader_tell\n"); - - /* Tell isn't used so just return 0 */ - return 0; -} - -/* Returns the total length of the source stream, in bytes. */ -static int32_t mpc_reader_get_size(void *const data) { - mpc_decoder_t *const this = (mpc_decoder_t *) data; - - lprintf("mpc_reader_get_size\n"); - - return this->file_size; -} - -/* True if the stream is a seekable stream. */ -static mpc_bool_t mpc_reader_canseek(void *data) { - lprintf("mpc_reader_canseek\n"); - - return TRUE; -} - -/** - * @brief Convert a array of floating point samples into 16-bit signed integer samples - * @param f Floating point samples array (origin) - * @param s16 16-bit signed integer samples array (destination) - * @param samples Number of samples to convert - * - * @todo This same work is being done in many decoders to adapt the output of - * the decoder to what the audio output can actually use, this should be - * done by the audio_output loop, not by the decoders. - */ -static inline void float_to_int(const float *const _f, int16_t *const s16, const int samples) { - int i; - for (i = 0; i < samples; i++) { - const float f = _f[i] * 32767; - if (f > INT16_MAX) - s16[i] = INT16_MAX; - else if (f < INT16_MIN) - s16[i] = INT16_MIN; - else - s16[i] = f; - /* printf("samples[%d] = %f, %d\n", i, _f[i], s16[num_channels*i]); */ - } -} - -/* Decode a musepack frame */ -static int mpc_decode_frame (mpc_decoder_t *this) { - float buffer[MPC_DECODER_BUFFER_LENGTH]; - uint32_t frames; - - lprintf("mpd_decode_frame\n"); - - frames = mpc_decoder_decode(&this->decoder, buffer, 0, 0); - - if (frames > 0) { - audio_buffer_t *audio_buffer; - int16_t *int_samples; - - lprintf("got %d samples\n", frames); - - /* Get audio buffer */ - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - audio_buffer->vpts = 0; - audio_buffer->num_frames = frames; - - /* Convert samples */ - int_samples = (int16_t *) audio_buffer->mem; - float_to_int(buffer, int_samples, frames*this->channels); - - /* Output converted samples */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - } - - return frames; -} - -/************************************************************************** - * xine audio plugin functions - *************************************************************************/ - -static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - mpc_decoder_t *this = (mpc_decoder_t *) this_gen; - int err; - - lprintf("mpc_decode_data\n"); - - if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED)) - return; - - /* We don't handle special buffers */ - if (buf->decoder_flags & BUF_FLAG_SPECIAL) - return; - - /* Read header */ - if (buf->decoder_flags & BUF_FLAG_HEADER) { - - lprintf("header\n"); - - /* File size is in decoder_info[0] */ - this->file_size = buf->decoder_info[0]; - - /* Initialise the data accumulation buffer */ - this->buf = xine_xmalloc(INIT_BUFSIZE); - this->buf_max = INIT_BUFSIZE; - this->read = 0; - this->size = 0; - - /* Initialise the reader */ - this->reader.read = mpc_reader_read; - this->reader.seek = mpc_reader_seek; - this->reader.tell = mpc_reader_tell; - this->reader.get_size = mpc_reader_get_size; - this->reader.canseek = mpc_reader_canseek; - this->reader.data = this; - - /* Copy header to buffer */ - xine_fast_memcpy(this->buf, buf->content, buf->size); - this->size = buf->size; - - /* Initialise and read stream info */ - mpc_streaminfo_init(&this->streaminfo); - - if ((err = mpc_streaminfo_read(&this->streaminfo, &this->reader))) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("libmusepack: mpc_streaminfo_read failed: %d\n"), err); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - return; - } - - this->sample_rate = this->streaminfo.sample_freq; - this->channels = this->streaminfo.channels; - this->bits_per_sample = 16; - - /* After the header the demuxer starts sending data from an offset - * of 28 bytes */ - this->size = 28; - - /* We need to keep track of the current frame so we now when we've - * reached the end of the stream */ - this->current_frame = 0; - - /* Setup the decoder */ - mpc_decoder_setup(&this->decoder, &this->reader); - this->decoder_ok = 0; - - /* Take this opportunity to initialize stream/meta information */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, - "Musepack (libmusepack)"); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, - (int) this->streaminfo.average_bitrate); - - return; - } - - lprintf("data: %u size=%u read=%u\n", buf->size, this->size, this->read); - - /* if the audio output is not open yet, open the audio output */ - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) ( - this->stream->audio_out, - this->stream, - this->bits_per_sample, - this->sample_rate, - _x_ao_channels2mode(this->channels)); - } - - /* if the audio still isn't open, do not go any further with the decode */ - if (!this->output_open) - return; - - /* If we run out of space in our internal buffer we discard what's - * already been read */ - if (((this->size + buf->size) > this->buf_max) && this->read) { - lprintf("discarding read data\n"); - this->size -= this->read; - memmove(this->buf, &this->buf[this->read], this->size); - this->read = 0; - } - - /* If there still isn't space we have to increase the size of the - * internal buffer */ - if ((this->size + buf->size) > this->buf_max) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libmusepack: increasing internal buffer size\n"); - this->buf_max += 2*buf->size; - this->buf = realloc(this->buf, this->buf_max); - } - - /* Copy data */ - xine_fast_memcpy(&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - /* Time to decode */ - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - /* Increment frame count */ - if (this->current_frame++ == this->streaminfo.frames) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("libmusepack: data after last frame ignored\n")); - return; - } - - if (!this->decoder_ok) { - /* We require MPC_DECODER_MEMSIZE bytes to initialise the decoder */ - if ((this->size - this->read) >= MPC_DECODER_MEMSIZE) { - lprintf("initialise"); - - if (!mpc_decoder_initialize(&this->decoder, &this->streaminfo)) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("libmusepack: mpc_decoder_initialise failed\n")); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - return; - } - - this->decoder_ok = 1; - } else { - /* Not enough data yet */ - return; - } - } - - /* mpc_decoder_decode may cause a read of MPC_DECODER_MEMSIZE/2 bytes so - * make sure we have enough data available */ - if ((this->size - this->read) >= MPC_DECODER_MEMSIZE2) { - lprintf("decoding\n"); - - if ((err = mpc_decode_frame(this)) < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("libmusepack: mpc_decoder_decode failed: %d\n"), err); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - return; - } - } - - /* If we are at the end of the stream we decode the remaining frames as we - * know we'll have enough data */ - if (this->current_frame == this->streaminfo.frames) { - lprintf("flushing buffers\n"); - - do { - if ((err = mpc_decode_frame(this)) < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("libmusepack: mpc_decoder_decode failed: %d\n"), err); - } - } while (err > 0); - - lprintf("buffers flushed\n"); - } - } -} - -static void mpc_reset (audio_decoder_t *this_gen) { - mpc_decoder_t *this = (mpc_decoder_t *) this_gen; - - this->size = 0; - this->read = 0; -} - -static void mpc_discontinuity (audio_decoder_t *this_gen) { - /* mpc_decoder_t *this = (mpc_decoder_t *) this_gen; */ -} - -static void mpc_dispose (audio_decoder_t *this_gen) { - - mpc_decoder_t *this = (mpc_decoder_t *) this_gen; - - /* close the audio output */ - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - /* free anything that was allocated during operation */ - free(this->buf); - - free(this); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - mpc_decoder_t *this ; - - this = (mpc_decoder_t *) xine_xmalloc (sizeof (mpc_decoder_t)); - - /* connect the member functions */ - this->audio_decoder.decode_data = mpc_decode_data; - this->audio_decoder.reset = mpc_reset; - this->audio_decoder.discontinuity = mpc_discontinuity; - this->audio_decoder.dispose = mpc_dispose; - - /* connect the stream */ - this->stream = stream; - - /* audio output is not open at the start */ - this->output_open = 0; - - /* no buffer yet */ - this->buf = NULL; - - /* initialize the basic audio parameters */ - this->channels = 0; - this->sample_rate = 0; - this->bits_per_sample = 0; - - /* return the newly-initialized audio decoder */ - return &this->audio_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - mpc_class_t *this ; - - this = (mpc_class_t *) xine_xmalloc (sizeof (mpc_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "mpc"; - this->decoder_class.description = N_("mpc: musepack audio decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_MPC, - 0 -}; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* { type, API version, "name", version, special_info, init_function }, */ - { PLUGIN_AUDIO_DECODER, 16, "mpc", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - -- cgit v1.2.3 From c57821405a657216e41e9c9e8ddaed9996af2350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 23:08:08 +0100 Subject: Rename libxinvadec directory in video_dec. --HG-- rename : src/libxinevdec/Makefile.am => src/video_dec/Makefile.am rename : src/libxinevdec/bitplane.c => src/video_dec/bitplane.c rename : src/libxinevdec/foovideo.c => src/video_dec/foovideo.c rename : src/libxinevdec/gdkpixbuf.c => src/video_dec/gdkpixbuf.c rename : src/libxinevdec/image.c => src/video_dec/image.c rename : src/libxinevdec/rgb.c => src/video_dec/rgb.c rename : src/libxinevdec/yuv.c => src/video_dec/yuv.c --- src/Makefile.am | 2 +- src/libxinevdec/Makefile.am | 38 -- src/libxinevdec/bitplane.c | 1554 ------------------------------------------- src/libxinevdec/foovideo.c | 281 -------- src/libxinevdec/gdkpixbuf.c | 294 -------- src/libxinevdec/image.c | 273 -------- src/libxinevdec/rgb.c | 447 ------------- src/libxinevdec/yuv.c | 373 ----------- src/video_dec/Makefile.am | 38 ++ src/video_dec/bitplane.c | 1554 +++++++++++++++++++++++++++++++++++++++++++ src/video_dec/foovideo.c | 281 ++++++++ src/video_dec/gdkpixbuf.c | 294 ++++++++ src/video_dec/image.c | 273 ++++++++ src/video_dec/rgb.c | 447 +++++++++++++ src/video_dec/yuv.c | 373 +++++++++++ 15 files changed, 3261 insertions(+), 3261 deletions(-) delete mode 100644 src/libxinevdec/Makefile.am delete mode 100644 src/libxinevdec/bitplane.c delete mode 100644 src/libxinevdec/foovideo.c delete mode 100644 src/libxinevdec/gdkpixbuf.c delete mode 100644 src/libxinevdec/image.c delete mode 100644 src/libxinevdec/rgb.c delete mode 100644 src/libxinevdec/yuv.c create mode 100644 src/video_dec/Makefile.am create mode 100644 src/video_dec/bitplane.c create mode 100644 src/video_dec/foovideo.c create mode 100644 src/video_dec/gdkpixbuf.c create mode 100644 src/video_dec/image.c create mode 100644 src/video_dec/rgb.c create mode 100644 src/video_dec/yuv.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 816cfa07c..330b099a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ SUBDIRS = \ audio_out \ audio_dec \ video_out \ + video_dec \ dxr3 \ input \ demuxers \ @@ -18,7 +19,6 @@ SUBDIRS = \ libspudvb \ libsputext \ libw32dll \ - libxinevdec \ libreal \ post \ combined \ diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am deleted file mode 100644 index 321d70c1f..000000000 --- a/src/libxinevdec/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -EXTRA_DIST = foovideo.c - -if ENABLE_IMAGEMAGICK -image_module = xineplug_decode_image.la -endif - -if ENABLE_GDK_PIXBUF -gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la -endif - -xineplug_LTLIBRARIES = $(image_module) \ - $(gdkpixbuf_module) \ - $(theora_module) \ - xineplug_decode_bitplane.la \ - xineplug_decode_rgb.la \ - xineplug_decode_yuv.la - -xineplug_decode_bitplane_la_SOURCES = bitplane.c -xineplug_decode_bitplane_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) - -xineplug_decode_rgb_la_SOURCES = rgb.c -xineplug_decode_rgb_la_LIBADD = $(XINE_LIB) - -xineplug_decode_yuv_la_SOURCES = yuv.c -xineplug_decode_yuv_la_LIBADD = $(XINE_LIB) - -xineplug_decode_image_la_SOURCES = image.c -xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(WAND_LIBS) -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) diff --git a/src/libxinevdec/bitplane.c b/src/libxinevdec/bitplane.c deleted file mode 100644 index 327e14aee..000000000 --- a/src/libxinevdec/bitplane.c +++ /dev/null @@ -1,1554 +0,0 @@ -/* - * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Bitplane "Decoder" by Manfred Tremmel (Manfred.Tremmel@iiv.de) - * Converts Amiga typical bitplane pictures to a YUV2 map - * suitable for display under xine. It's based on the rgb-decoder - * and the development documentation from the Amiga Developer CD - * - * Supported formats: - * - uncompressed and byterun1 compressed ILBM data - * - IFF ANIM compression methods OPT 5, 7 (long and short) and - * 8 (long and short) - * - untested (found no testfiles) IFF-ANIM OPT 3, 4 and 6 - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#include "demuxers/iff.h" - -#define IFF_REPLACE_BYTE_SIMPLE(ptr, old_data, new_data, colorindexx ) { \ - register uint8_t *index_ptr = ptr; \ - register uint8_t colorindex = colorindexx; \ - *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x80) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x40) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x20) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x10) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x08) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x04) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x02) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ - old_data = new_data; \ -} - -#define IFF_REPLACE_BYTE(ptr, yuvy, yuvu, yuvv, yuv_palette, old_data, new_data, colorindexx ) { \ - register uint8_t *index_ptr = ptr; \ - register uint8_t colorindex = colorindexx; \ - register uint8_t *yuv_y = yuvy; \ - register uint8_t *yuv_u = yuvu; \ - register uint8_t *yuv_v = yuvv; \ - *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x80) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x40) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x20) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x10) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x08) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x04) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x02) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ - yuv_index = *index_ptr * 4; \ - *yuv_y = yuv_palette[yuv_index++]; \ - *yuv_u = yuv_palette[yuv_index++]; \ - *yuv_v = yuv_palette[yuv_index]; \ - old_data = new_data; \ -} - -#define IFF_REPLACE_SHORT_SIMPLE(ptr_s, old_data_s, new_data_s, colorindexx_s ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ - uint8_t *xold_data = (uint8_t *)old_data_s; \ - uint8_t *xnew_data = (uint8_t *)new_data_s; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ -} - -#define IFF_REPLACE_SHORT(ptr_s, yuvy_s, yuvu_s, yuvv_s, yuv_palette_s, old_data_s, new_data_s, colorindexx_s ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ - uint8_t *xold_data = (uint8_t *)old_data_s; \ - uint8_t *xnew_data = (uint8_t *)new_data_s; \ - uint8_t *xyuv_y = yuvy_s; \ - uint8_t *xyuv_u = yuvu_s; \ - uint8_t *xyuv_v = yuvv_s; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ -} - -#define IFF_REPLACE_LONG_SIMPLE(ptr_l, old_data_l, new_data_l, colorindexx_l ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ - uint8_t *xold_data = (uint8_t *)old_data_l; \ - uint8_t *xnew_data = (uint8_t *)new_data_l; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ -} - -#define IFF_REPLACE_LONG(ptr_l, yuvy_l, yuvu_l, yuvv_l, yuv_palette_l, old_data_l, new_data_l, colorindexx_l ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ - uint8_t *xold_data = (uint8_t *)old_data_l; \ - uint8_t *xnew_data = (uint8_t *)new_data_l; \ - uint8_t *xyuv_y = yuvy_l; \ - uint8_t *xyuv_u = yuvu_l; \ - uint8_t *xyuv_v = yuvv_l; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ -} - -typedef struct { - video_decoder_class_t decoder_class; -} bitplane_class_t; - -typedef struct bitplane_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - bitplane_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; /* 0 = draw picture, 1 = skip it */ - int framenumber; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - int size_uk; /* size of unkompressed bitplane */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - int num_pixel; /* number pixel */ - double ratio; /* the width to height ratio */ - int bytes_per_pixel; - int num_bitplanes; - int camg_mode; - int is_ham; - - unsigned char yuv_palette[256 * 4]; - unsigned char rgb_palette[256 * 4]; - yuv_planes_t yuv_planes; - yuv_planes_t yuv_planes_hist; - - uint8_t *buf_uk; /* uncompressed buffer */ - uint8_t *buf_uk_hist; /* uncompressed buffer historic */ - uint8_t *index_buf; /* index buffer (for indexed pics) */ - uint8_t *index_buf_hist;/* index buffer historic */ - -} bitplane_decoder_t; - -/* create a new buffer and decde a byterun1 decoded buffer into it */ -static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed, - int size_compressed, - int size_uncompressed) { - - /* BytRun1 decompression */ - int pixel_ptr = 0; - int i = 0; - int j = 0; - - uint8_t *uncompressed = xine_xmalloc( size_uncompressed ); - - while ( i < size_compressed && - pixel_ptr < size_uncompressed ) { - if( compressed[i] <= 127 ) { - j = compressed[i++]; - if( (i+j) > size_compressed ) { - free(uncompressed); - return NULL; - } - for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { - uncompressed[pixel_ptr++] = compressed[i++]; - } - } else if ( compressed[i] > 128 ) { - j = 256 - compressed[i++]; - if( i >= size_compressed ) { - free(uncompressed); - return NULL; - } - for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { - uncompressed[pixel_ptr++] = compressed[i]; - } - i++; - } - } - return uncompressed; -} - -/* create a new buffer with "normal" index or rgb numbers out of a bitplane */ -static void bitplane_decode_bitplane (uint8_t *bitplane_buffer, - uint8_t *index_buf, - int width, - int height, - int num_bitplanes, - int bytes_per_pixel ) { - - int rowsize = width / 8; - int pixel_ptr = 0; - int row_ptr = 0; - int palette_index = 0; - int i = 0; - int j = 0; - int row_i = 0; - int row_j = 0; - int palette_offset = 0; - int palette_index_rowsize = 0; - uint8_t color = 0; - uint8_t data = 0; - int bytes_per_pixel_8 = bytes_per_pixel * 8; - int rowsize_num_bitplanes = rowsize * num_bitplanes; - int width_bytes_per_pixel = width * bytes_per_pixel; - - for (i = 0; i < (height * width_bytes_per_pixel); index_buf[i++] = 0); - - /* decode Bitplanes to RGB/Index Numbers */ - for (row_ptr = 0; row_ptr < height; row_ptr++) { - - row_i = row_ptr * width_bytes_per_pixel; - row_j = row_ptr * rowsize_num_bitplanes; - - for (palette_index = 0; palette_index < num_bitplanes; palette_index++) { - - palette_offset = ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0); - color = bitplainoffeset[palette_index]; - palette_index_rowsize = palette_index * rowsize; - - for (pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - i = row_i + - (pixel_ptr * bytes_per_pixel_8) + - palette_offset; - j = row_j + palette_index_rowsize + pixel_ptr; - - data = bitplane_buffer[j]; - - index_buf[i] += ((data & 0x80) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x40) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x20) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x10) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x08) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x04) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x02) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x01) ? color : 0); - } - } - } -} - -/* create Buffer decode HAM6 and HAM8 to YUV color */ -static void bitplane_decode_ham (uint8_t *ham_buffer, - yuv_planes_t *yuv_planes, - int width, - int height, - int num_bitplanes, - int bytes_per_pixel, - unsigned char *rgb_palette ) { - - uint8_t *ham_buffer_work = ham_buffer; - uint8_t *ham_buffer_end = &ham_buffer[(width * height)]; - uint8_t *yuv_ptr_y = yuv_planes->y; - uint8_t *yuv_ptr_u = yuv_planes->u; - uint8_t *yuv_ptr_v = yuv_planes->v; - int i = 0; - int j = 0; - uint8_t r = 0; - uint8_t g = 0; - uint8_t b = 0; - /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */ - int hambits = num_bitplanes > 6 ? 6 : 4; - /* the other bits contain the real data, dreate a mask out of it */ - int maskbits = 8 - hambits; - int mask = ( 1 << hambits ) - 1; - - for(; ham_buffer_work < ham_buffer_end; j = *ham_buffer_work++) { - i = (j & mask); - switch ( j >> hambits ) { - case HAMBITS_CMAP: - /* Take colors from palette */ - r = rgb_palette[i * 4 + 0]; - g = rgb_palette[i * 4 + 1]; - b = rgb_palette[i * 4 + 2]; - break; - case HAMBITS_BLUE: - /* keep red and green and modify blue */ - b = i << maskbits; - b |= b >> hambits; - break; - case HAMBITS_RED: - /* keep green and blue and modify red */ - r = i << maskbits; - r |= r >> hambits; - break; - case HAMBITS_GREEN: - /* keep red and blue and modify green */ - g = i << maskbits; - g |= g >> hambits; - break; - default: - break; - } - *yuv_ptr_y++ = COMPUTE_Y(r, g, b); - *yuv_ptr_u++ = COMPUTE_U(r, g, b); - *yuv_ptr_v++ = COMPUTE_V(r, g, b); - } -} - -/* decoding method 3 */ -static void bitplane_sdelta_opt_3 (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t palette_index = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint16_t *ptr = NULL; - uint16_t *planeptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint16_t *rowworkptr = NULL; - int16_t s = 0; - int16_t size = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t yuv_index = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); - if( data != (uint16_t *)this->buf ) { - /* This 8 Pointers are followd by another 8 */ - ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); - - /* in this case, I think big/little endian is not important ;-) */ - while( *data != 0xFFFF) { - row_ptr = 0; - size = _X_BE_16(data); - data++; - if( size >= 0 ) { - rowworkptr = planeptr + size; - pixel_ptr_bit = size * 16; - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], - &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], - &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - } else { - size = 0 - size + 2; - rowworkptr = planeptr + size; - pixel_ptr_bit = size * 16; - s = _X_BE_16(data); - data++; - while( s--) { - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], - &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], - &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr++; - data++; - } - } - - - - - size = _X_BE_16(ptr); - ptr++; - if (size < 0) { - for (s = size; s < 0; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } - else { - for (s = 0; s < size; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } - } - } - } -} - -/* decoding method 4 */ -static void bitplane_set_dlta_short (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t palette_index = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint16_t *ptr = NULL; - uint16_t *planeptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint16_t *rowworkptr = NULL; - int16_t s = 0; - int16_t size = 0; - uint16_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t yuv_index = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); - if( data != (uint16_t *)this->buf ) { - /* This 8 Pointers are followd by another 8 */ - ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); - - /* in this case, I think big/little endian is not important ;-) */ - while( *ptr != 0xFFFF) { - pixel_ptr = _X_BE_16(ptr); - pixel_ptr_bit = pixel_ptr * 16; - row_ptr = 0; - rowworkptr = planeptr + pixel_ptr; - ptr++; - size = _X_BE_16(ptr); - ptr++; - if (size < 0) { - for (s = size; s < 0; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - for (s = 0; s < size; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } - } - } - } -} - -/* decoding method 5 */ -static void bitplane_dlta_5 (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 8; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t delta_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint8_t *planeptr = NULL; - uint8_t *rowworkptr = NULL; - uint8_t *picture_end = this->buf_uk + (rowsize_all_planes * this->height); - uint8_t *data = NULL; - uint8_t *data_end = this->buf + this->size; - uint8_t op_count = 0; - uint8_t op = 0; - uint8_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = &this->buf_uk[(palette_index * rowsize)]; - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - delta_offset = _X_BE_32(&deltadata[palette_index]); - - if (delta_offset > 0) { - data = this->buf + delta_offset; - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = planeptr + pixel_ptr; - pixel_ptr_bit = pixel_ptr * 8; - row_ptr = 0; - /* execute ops */ - for( op_count = *data++; op_count; op_count--) { - op = *data++; - if (op & 0x80) { - /* Uniq ops */ - count = op & 0x7f; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_BYTE( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = *data++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_BYTE( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 7 (short version) */ -static void bitplane_dlta_7_short (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t opcode_offset = 0; - uint32_t data_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint8_t *planeptr = NULL; - uint16_t *rowworkptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint8_t *op_ptr = NULL; - uint8_t op_count = 0; - uint8_t op = 0; - uint8_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = &this->buf_uk[(palette_index * rowsize * 2)]; - /* find opcode and data offset (up to 8 pointers, one for every bitplane */ - opcode_offset = _X_BE_32(&deltadata[palette_index]); - data_offset = _X_BE_32(&deltadata[palette_index + 8]); - - if (opcode_offset > 0 && data_offset > 0) { - data = (uint16_t *)(&this->buf[data_offset]); - op_ptr = this->buf + opcode_offset; - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = (uint16_t *)(&planeptr[pixel_ptr * 2]); - pixel_ptr_bit = pixel_ptr * 16; - row_ptr = 0; - /* execute ops */ - for( op_count = *op_ptr++; op_count; op_count--) { - op = *op_ptr++; - if (op & 0x80) { - /* Uniq ops */ - count = op & 0x7f; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = *op_ptr++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 7 (long version) */ -static void bitplane_dlta_7_long (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 32; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t opcode_offset = 0; - uint32_t data_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint8_t *planeptr = NULL; - uint32_t *rowworkptr = NULL; - uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); - uint32_t *data = NULL; - uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); - uint8_t *op_ptr = NULL; - uint8_t op_count = 0; - uint8_t op = 0; - uint8_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - planeptr = &this->buf_uk[(palette_index * rowsize * 4)]; - /* find opcode and data offset (up to 8 pointers, one for every bitplane */ - opcode_offset = _X_BE_32(&deltadata[palette_index]); - data_offset = _X_BE_32(&deltadata[palette_index + 8]); - - if (opcode_offset > 0 && data_offset > 0) { - data = (uint32_t *)(&this->buf[data_offset]); - op_ptr = this->buf + opcode_offset; - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = (uint32_t *)(&planeptr[pixel_ptr * 4]); - pixel_ptr_bit = pixel_ptr * 32; - row_ptr = 0; - /* execute ops */ - for( op_count = *op_ptr++; op_count; op_count--) { - op = *op_ptr++; - if (op & 0x80) { - /* Uniq ops */ - count = op & 0x7f; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = *op_ptr++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 8 short */ -static void bitplane_dlta_8_short (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t delta_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t row_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint16_t *planeptr = NULL; - uint16_t *rowworkptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint16_t op_count = 0; - uint16_t op = 0; - uint16_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - delta_offset = _X_BE_32(&deltadata[palette_index]); - - if (delta_offset > 0) { - data = (uint16_t *)(&this->buf[delta_offset]); - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = planeptr + pixel_ptr; - pixel_ptr_bit = pixel_ptr * 16; - row_ptr = 0; - /* execute ops */ - op_count = _X_BE_16(data); - data++; - for( ; op_count; op_count--) { - op = _X_BE_16(data); - data++; - if (op & 0x8000) { - /* Uniq ops */ - count = op & 0x7fff; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = _X_BE_16(data); - data++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 8 long */ -static void bitplane_dlta_8_long (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 32; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t delta_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint32_t *planeptr = NULL; - uint32_t *rowworkptr = NULL; - uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); - uint32_t *data = NULL; - uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); - uint32_t op_count = 0; - uint32_t op = 0; - uint32_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint32_t *)(&this->buf_uk[(palette_index * rowsize * 4)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - delta_offset = _X_BE_32(&deltadata[palette_index]); - - if (delta_offset > 0) { - data = (uint32_t *)(&this->buf[delta_offset]); - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = planeptr + pixel_ptr; - pixel_ptr_bit = pixel_ptr * 32; - row_ptr = 0; - /* execute ops */ - op_count = _X_BE_32(data); - data++; - for( ; op_count; op_count--) { - op = _X_BE_32(data); - data++; - if (op & 0x80000000) { - /* Uniq ops */ - count = op & 0x7fffffff; /* get count */ - while(count--) { - if (data <= data_end || rowworkptr <= picture_end) { - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[((row_ptr * this->width) + pixel_ptr_bit)], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = _X_BE_32(data); - data++; - while(count--) { - if (data <= data_end && rowworkptr <= picture_end) { - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -/* bitplane_decode_bitplane(this->buf_uk, this->index_buf, this->width, this->height, this->num_bitplanes, 1);*/ -} - -static void bitplane_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; - xine_bmiheader *bih = 0; - palette_entry_t *palette = 0; - AnimHeader *anhd = NULL; - int i = 0; - int j = 0; - int buf_ptr = 0; - unsigned char r = 0; - unsigned char g = 0; - unsigned char b = 0; - uint8_t *buf_exchange = NULL; - - vo_frame_t *img = 0; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && - (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { - palette = (palette_entry_t *)buf->decoder_info_ptr[2]; - - for (i = 0; i < buf->decoder_info[2]; i++) { - this->yuv_palette[i * 4 + 0] = - COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 1] = - COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 2] = - COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); - this->rgb_palette[i * 4 + 0] = palette[i].r; - this->rgb_palette[i * 4 + 1] = palette[i].g; - this->rgb_palette[i * 4 + 2] = palette[i].b; - } - - /* EHB Pictures not allways contain all 64 colors, sometimes only */ - /* the first 32 are included and sometimes all 64 colors are provide,*/ - /* but second 32 are only stupid dirt, so recalculate them */ - if (((this->num_bitplanes == 6) && - (buf->decoder_info[2] == 32)) || - (this->camg_mode & CAMG_EHB)) { - for (i = 32; i < 64; i++) { - this->rgb_palette[i * 4 + 0] = palette[(i-32)].r / 2; - this->rgb_palette[i * 4 + 1] = palette[(i-32)].g / 2; - this->rgb_palette[i * 4 + 2] = palette[(i-32)].b / 2; - this->yuv_palette[i * 4 + 0] = - COMPUTE_Y(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); - this->yuv_palette[i * 4 + 1] = - COMPUTE_U(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); - this->yuv_palette[i * 4 + 2] = - COMPUTE_V(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); - } - } - - return; - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - bih = (xine_bmiheader *) buf->content; - this->width = (bih->biWidth + 15) & ~0x0f; - this->height = bih->biHeight; - this->num_pixel = this->width * this->height; - this->ratio = (double)this->width/(double)this->height; - this->video_step = buf->decoder_info[1]; - /* Palette based Formates use up to 8 Bit per pixel, always use 8 Bit if less */ - this->bytes_per_pixel = (bih->biBitCount + 1) / 8; - if( this->bytes_per_pixel < 1 ) - this->bytes_per_pixel = 1; - - /* New Buffer for indexes (palette based formats) */ - this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - - this->num_bitplanes = bih->biPlanes; - this->camg_mode = bih->biCompression; - if( this->camg_mode & CAMG_HAM ) - this->is_ham = 1; - else - this->is_ham = 0; - - if( buf->decoder_info[2] != buf->decoder_info[3] && - buf->decoder_info[3] > 0 ) { - this->ratio *= buf->decoder_info[2]; - this->ratio /= buf->decoder_info[3]; - } - - if( (bih->biCompression & CAMG_HIRES) && - !(bih->biCompression & CAMG_LACE) ) { - if( (buf->decoder_info[2] * 16) > (buf->decoder_info[3] * 10) ) - this->ratio /= 2.0; - } - - if( !(bih->biCompression & CAMG_HIRES) && - (bih->biCompression & CAMG_LACE) ) { - if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 16) ) - this->ratio *= 2.0; - } - - free (this->buf); - this->bufsize = VIDEOBUFSIZE; - this->buf = xine_xmalloc(this->bufsize); - this->size = 0; - this->framenumber = 0; - - init_yuv_planes(&this->yuv_planes, this->width, this->height); - init_yuv_planes(&this->yuv_planes_hist, this->width, this->height); - - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->decoder_ok = 1; - - /* load the stream/meta info */ - switch( buf->type ) { - case BUF_VIDEO_BITPLANE: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Uncompressed bitplane"); - break; - case BUF_VIDEO_BITPLANE_BR1: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ByteRun1 bitplane"); - break; - default: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Unknown bitplane"); - break; - } - - return; - } else if (this->decoder_ok) { - - this->skipframes = 0; - this->framenumber++; - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) - this->video_step = buf->decoder_info[0]; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - anhd = (AnimHeader *)(buf->decoder_info_ptr[0]); - - if( (this->buf_uk == NULL) || - (anhd == NULL) || - (anhd->operation == IFF_ANHD_ILBM) ) { - - /* iterate through each row */ - buf_ptr = 0; - this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); - - if( this->buf_uk_hist != NULL ) - xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); - switch( buf->type ) { - case BUF_VIDEO_BITPLANE: - /* uncompressed Buffer, set decoded_buf pointer direct to input stream */ - if( this->buf_uk == NULL ) - this->buf_uk = xine_xmalloc( (this->size) ); - xine_fast_memcpy (this->buf_uk, this->buf, this->size); - break; - case BUF_VIDEO_BITPLANE_BR1: - /* create Buffer for decompressed bitmap */ - this->buf_uk = bitplane_decode_byterun1( - this->buf, /* compressed buffer */ - this->size, /* size of compressed data */ - this->size_uk ); /* size of uncompressed data */ - - if( this->buf_uk == NULL ) { - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: error doing ByteRun1 decompression\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - } - /* set pointer to decompressed Buffer */ - break; - default: - break; - } - bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */ - this->index_buf, /* index buffer */ - this->width, /* width */ - this->height, /* hight */ - this->num_bitplanes, /* number bitplanes */ - this->bytes_per_pixel); /* used Bytes per pixel */ - - if ((this->bytes_per_pixel == 1) && - (this->is_ham == 0) ) { - buf_exchange = this->index_buf; - for (i = 0; i < (this->height * this->width); i++) { - j = *buf_exchange++ * 4; - this->yuv_planes.y[i] = this->yuv_palette[j++]; - this->yuv_planes.u[i] = this->yuv_palette[j++]; - this->yuv_planes.v[i] = this->yuv_palette[j]; - } - } - if( this->buf_uk_hist == NULL ) { - this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); - xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); - xine_fast_memcpy (this->index_buf_hist, this->index_buf, - (this->num_pixel * this->bytes_per_pixel)); - xine_fast_memcpy (this->yuv_planes_hist.y, this->yuv_planes.y, (this->num_pixel)); - xine_fast_memcpy (this->yuv_planes_hist.u, this->yuv_planes.u, (this->num_pixel)); - xine_fast_memcpy (this->yuv_planes_hist.v, this->yuv_planes.v, (this->num_pixel)); - } - } else { - /* when no start-picture is given, create a empty one */ - if( this->buf_uk_hist == NULL ) { - this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); - this->buf_uk = xine_xmalloc( (this->size_uk) ); - this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); - for (i = 0; i < this->size_uk; i++) { - this->buf_uk[i] = 0; - this->buf_uk_hist[i] = 0; - } - } - if( this->index_buf == NULL ) { - this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - for (i = 0; i < (this->num_pixel * this->bytes_per_pixel); i++) { - this->index_buf[i] = 0; - this->index_buf_hist[i] = 0; - } - } - - switch( anhd->operation ) { - /* also known as IFF-ANIM OPT1 (never seen in real world) */ - case IFF_ANHD_XOR: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: Anim Opt 1 is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - /* also known as IFF-ANIM OPT2 (never seen in real world) */ - case IFF_ANHD_LDELTA: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: Anim Opt 2 is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - /* also known as IFF-ANIM OPT3 */ - case IFF_ANHD_SDELTA: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT3"); - bitplane_sdelta_opt_3 ( this ); - return; - break; - /* also known as IFF-ANIM OPT4 (never seen in real world) */ - case IFF_ANHD_SLDELTA: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT4 (SLDELTA)"); - bitplane_set_dlta_short ( this ); - break; - /* also known as IFF-ANIM OPT5 */ - case IFF_ANHD_BVDELTA: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT5 (BVDELTA)"); - bitplane_dlta_5(this); - break; - /* IFF-ANIM OPT6 is exactly the same as OPT5, but for stereo-displays */ - /* first picture is on the left display, second on the right, third on */ - /* the left, forth on right, ... Only display left picture on mono display*/ - case IFF_ANHD_STEREOO5: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT6 (BVDELTA STEREO)"); - bitplane_dlta_5(this); - if( this->framenumber % 2 == 0 ) - this->skipframes = 1; - return; - break; - case IFF_ANHD_OPT7: - if(anhd->bits == 0) { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (SHORT)"); - bitplane_dlta_7_short(this); - } else { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (LONG)"); - bitplane_dlta_7_long(this); - } - break; - case IFF_ANHD_OPT8: - if(anhd->bits == 0) { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (SHORT)"); - bitplane_dlta_8_short(this); - } else { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (LONG)"); - bitplane_dlta_8_long(this); - } - break; - case IFF_ANHD_ASCIIJ: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: Anim ASCIIJ is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - default: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: This anim-type is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - } - /* change old bitmap buffer (which now is the new one) with new buffer */ - buf_exchange = this->buf_uk; - this->buf_uk = this->buf_uk_hist; - this->buf_uk_hist = buf_exchange; - /* do the same with the index buffer */ - buf_exchange = this->index_buf; - this->index_buf = this->index_buf_hist; - this->index_buf_hist = buf_exchange; - /* and also with yuv buffer */ - buf_exchange = this->yuv_planes.y; - this->yuv_planes.y = this->yuv_planes_hist.y; - this->yuv_planes_hist.y = buf_exchange; - buf_exchange = this->yuv_planes.u; - this->yuv_planes.u = this->yuv_planes_hist.u; - this->yuv_planes_hist.u = buf_exchange; - buf_exchange = this->yuv_planes.v; - this->yuv_planes.v = this->yuv_planes_hist.v; - this->yuv_planes_hist.v = buf_exchange; - } - - if( this->skipframes == 0 ) { - switch (this->bytes_per_pixel) { - case 1: - /* HAM-pictrues need special handling */ - if( this->is_ham ) { - /* Decode HAM-Pictures to YUV */ - bitplane_decode_ham( this->index_buf, /* HAM-bitplane buffer */ - &(this->yuv_planes), /* YUV buffer */ - this->width, /* width */ - this->height, /* hight */ - this->num_bitplanes, /* number bitplanes */ - this->bytes_per_pixel, /* used Bytes per pixel */ - this->rgb_palette); /* Palette (RGB) */ - } - break; - case 3: - buf_exchange = this->index_buf; - for (i = 0; i < (this->height * this->width); i++) { - r = *buf_exchange++; - g = *buf_exchange++; - b = *buf_exchange++; - - this->yuv_planes.y[i] = COMPUTE_Y(r, g, b); - this->yuv_planes.u[i] = COMPUTE_U(r, g, b); - this->yuv_planes.v[i] = COMPUTE_V(r, g, b); - } - break; - default: - break; - } - - yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); - - img->draw(img, this->stream); - } - img->free(img); - - this->size = 0; - if ( buf->decoder_info[1] > 90000 ) - xine_usec_sleep(buf->decoder_info[1]); - } - } -} - -/* - * This function is called when xine needs to flush the system. Not - * sure when or if this is used or even if it needs to do anything. - */ -static void bitplane_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void bitplane_reset (video_decoder_t *this_gen) { - bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; - - this->size = 0; -} - -static void bitplane_discontinuity (video_decoder_t *this_gen) { -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void bitplane_dispose (video_decoder_t *this_gen) { - bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; - - free (this->buf); - free (this->buf_uk); - free (this->buf_uk_hist); - free (this->index_buf); - free (this->index_buf_hist); - free (this->index_buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - bitplane_decoder_t *this = (bitplane_decoder_t *) xine_xmalloc (sizeof (bitplane_decoder_t)); - - this->video_decoder.decode_data = bitplane_decode_data; - this->video_decoder.flush = bitplane_flush; - this->video_decoder.reset = bitplane_reset; - this->video_decoder.discontinuity = bitplane_discontinuity; - this->video_decoder.dispose = bitplane_dispose; - this->size = 0; - - this->stream = stream; - this->class = (bitplane_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - this->buf_uk = NULL; - this->index_buf = NULL; - this->index_buf = NULL; - - return &this->video_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - bitplane_class_t *this = (bitplane_class_t *) xine_xmalloc (sizeof (bitplane_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "bitplane"; - this->decoder_class.description = N_("Raw bitplane video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static const uint32_t video_types[] = { - BUF_VIDEO_BITPLANE, - BUF_VIDEO_BITPLANE_BR1, - 0 -}; - -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "bitplane", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/foovideo.c b/src/libxinevdec/foovideo.c deleted file mode 100644 index 49c63422c..000000000 --- a/src/libxinevdec/foovideo.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * foovideo.c: This is a reference video decoder for the xine multimedia - * player. It really works too! It will output frames of packed YUY2 data - * where each byte in the map is the same value, which is 3 larger than the - * value from the last frame. This creates a slowly rotating solid color - * frame when the frames are played in succession. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#define VIDEOBUFSIZE 128*1024 - -typedef struct { - video_decoder_class_t decoder_class; -} foovideo_class_t; - -typedef struct foovideo_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - foovideo_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - double ratio; /* the width to height ratio */ - - /* these are variables exclusive to the foo video decoder */ - unsigned char current_yuv_byte; - -} foovideo_decoder_t; - -/************************************************************************** - * foovideo specific decode functions - *************************************************************************/ - -/************************************************************************** - * xine video plugin functions - *************************************************************************/ - -/* - * This function receives a buffer of data from the demuxer layer and - * figures out how to handle it based on its header flags. - */ -static void foovideo_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - xine_bmiheader *bih; - - vo_frame_t *img; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - free(this->buf); - - bih = (xine_bmiheader *) buf->content; - this->width = bih->biWidth; - this->height = bih->biHeight; - this->ratio = (double)this->width/(double)this->height; - - if (this->buf) - free (this->buf); - this->bufsize = VIDEOBUFSIZE; - this->buf = malloc(this->bufsize); - this->size = 0; - - /* take this opportunity to load the stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "foovideo"); - - /* do anything else relating to initializing this decoder */ - this->current_yuv_byte = 0; - - this->decoder_ok = 1; - - return; - } else if (this->decoder_ok) { - - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, - XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - - memset(img->base[0], this->current_yuv_byte, - this->width * this->height * 2); - this->current_yuv_byte += 3; - - img->draw(img, this->stream); - img->free(img); - - this->size = 0; - } - } -} - -/* - * This function is called when xine needs to flush the system. - */ -static void foovideo_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void foovideo_reset (video_decoder_t *this_gen) { - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - - this->size = 0; -} - -/* - * The decoder should forget any stored pts values here. - */ -static void foovideo_discontinuity (video_decoder_t *this_gen) { - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void foovideo_dispose (video_decoder_t *this_gen) { - - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - - free (this->buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -/* - * This function allocates, initializes, and returns a private video - * decoder structure. - */ -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - foovideo_decoder_t *this ; - - this = (foovideo_decoder_t *) xine_xmalloc (sizeof (foovideo_decoder_t)); - - this->video_decoder.decode_data = foovideo_decode_data; - this->video_decoder.flush = foovideo_flush; - this->video_decoder.reset = foovideo_reset; - this->video_decoder.discontinuity = foovideo_discontinuity; - this->video_decoder.dispose = foovideo_dispose; - this->size = 0; - - this->stream = stream; - this->class = (foovideo_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - - return &this->video_decoder; -} - -/* - * This function frees the video decoder class and any other memory that was - * allocated. - */ -static void dispose_class (video_decoder_class_t *this) { - free (this); -} - -/* - * This function allocates a private video decoder class and initializes - * the class's member functions. - */ -static void *init_plugin (xine_t *xine, void *data) { - - foovideo_class_t *this; - - this = (foovideo_class_t *) xine_xmalloc (sizeof (foovideo_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "foovideo"; - this->decoder_class.description = N_("foovideo: reference xine video decoder plugin"); - this->decoder_class.dispose = dispose_class; - - return this; -} - -/* - * This is a list of all of the internal xine video buffer types that - * this decoder is able to handle. Check src/xine-engine/buffer.h for a - * list of valid buffer types (and add a new one if the one you need does - * not exist). Terminate the list with a 0. - */ -static const uint32_t video_types[] = { - /* BUF_VIDEO_FOOVIDEO, */ - BUF_VIDEO_VQA, - BUF_VIDEO_SORENSON_V3, - 0 -}; - -/* - * This data structure combines the list of supported xine buffer types and - * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) - * will be used instead of a plugin with priority (n). - */ -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 5 /* priority */ -}; - -/* - * The plugin catalog entry. This is the only information that this plugin - * will export to the public. - */ -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* { type, API, "name", version, special_info, init_function } */ - { PLUGIN_VIDEO_DECODER, 19, "foovideo", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/gdkpixbuf.c b/src/libxinevdec/gdkpixbuf.c deleted file mode 100644 index 28c9c77c7..000000000 --- a/src/libxinevdec/gdkpixbuf.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * a gdk-pixbuf-based image video decoder - */ - - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "gdkpixbuf_video_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include -#include "bswap.h" - -#include - -typedef struct { - video_decoder_class_t decoder_class; - - /* - * private variables - */ - -} image_class_t; - - -typedef struct image_decoder_s { - video_decoder_t video_decoder; - - image_class_t *cls; - - xine_stream_t *stream; - int video_open; - - GdkPixbufLoader *loader; - -} image_decoder_t; - - -static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - image_decoder_t *this = (image_decoder_t *) this_gen; - GError *error = NULL; - - if (!this->video_open) { - lprintf("opening video\n"); - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->video_open = 1; - } - - if (this->loader == NULL) { - this->loader = gdk_pixbuf_loader_new (); - } - - if (gdk_pixbuf_loader_write (this->loader, buf->mem, buf->size, &error) == FALSE) { - lprintf("error loading image: %s\n", error->message); - g_error_free (error); - gdk_pixbuf_loader_close (this->loader, NULL); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - return; - } - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - GdkPixbuf *pixbuf; - int width, height, x, y, rowstride, n_channels, i; - guchar *img_buf; - yuv_planes_t yuv_planes; - vo_frame_t *img; - - /* - * this->image -> rgb data - */ - if (gdk_pixbuf_loader_close (this->loader, &error) == FALSE) { - lprintf("error loading image: %s\n", error->message); - g_error_free (error); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - return; - } - - pixbuf = gdk_pixbuf_loader_get_pixbuf (this->loader); - if (pixbuf != NULL) - g_object_ref (G_OBJECT (pixbuf)); - g_object_unref (this->loader); - this->loader = NULL; - - if (pixbuf == NULL) { - lprintf("error loading image\n"); - return; - } - - width = gdk_pixbuf_get_width (pixbuf) & ~1; /* must be even for init_yuv_planes */ - height = gdk_pixbuf_get_height (pixbuf); - img_buf = gdk_pixbuf_get_pixels (pixbuf); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); - - lprintf("image loaded successfully\n"); - - /* - * rgb data -> yuv_planes - */ - init_yuv_planes(&yuv_planes, width, height); - - n_channels = gdk_pixbuf_get_n_channels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - i = 0; - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - guchar *p; - p = img_buf + y * rowstride + x * n_channels; - - yuv_planes.y[i] = COMPUTE_Y (p[0], p[1], p[2]); - yuv_planes.u[i] = COMPUTE_U (p[0], p[1], p[2]); - yuv_planes.v[i] = COMPUTE_V (p[0], p[1], p[2]); - - i++; - } - } - gdk_pixbuf_unref (pixbuf); - - /* - * alloc and draw video frame - */ - img = this->stream->video_out->get_frame (this->stream->video_out, width, - height, (double)width/(double)height, - XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - img->pts = buf->pts; - img->duration = 3600; - img->bad_frame = 0; - - yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); - free_yuv_planes(&yuv_planes); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); - - img->draw(img, this->stream); - img->free(img); - } -} - - -static void image_flush (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * flush out any frames that are still stored in the decoder - */ -} - - -static void image_reset (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - - if (this->loader != NULL) { - gdk_pixbuf_loader_close (this->loader, NULL); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - } -} - - -static void image_discontinuity (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ -} - -static void image_dispose (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - if (this->video_open) { - lprintf("closing video\n"); - - this->stream->video_out->close(this->stream->video_out, this->stream); - this->video_open = 0; - } - - if (this->loader != NULL) { - gdk_pixbuf_loader_close (this->loader, NULL); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - } - - lprintf("closed\n"); - free (this); -} - - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, - xine_stream_t *stream) { - - image_class_t *cls = (image_class_t *) class_gen; - image_decoder_t *this; - - lprintf("opened\n"); - - g_type_init (); - - this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); - - this->video_decoder.decode_data = image_decode_data; - this->video_decoder.flush = image_flush; - this->video_decoder.reset = image_reset; - this->video_decoder.discontinuity = image_discontinuity; - this->video_decoder.dispose = image_dispose; - this->cls = cls; - this->stream = stream; - - /* - * initialisation of privates - */ - - return &this->video_decoder; -} - -/* - * image plugin class - */ -static void *init_class (xine_t *xine, void *data) { - - image_class_t *this; - - this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "gdkpixbuf"; - this->decoder_class.description = N_("gdk-pixbuf image video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - /* - * initialisation of privates - */ - - lprintf("class opened\n"); - - return this; -} - -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, BUF_VIDEO_JPEG, 0 }; - -static const decoder_info_t dec_info_image = { - supported_types, /* supported types */ - 7 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "gdkpixbuf", XINE_VERSION_CODE, &dec_info_image, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c deleted file mode 100644 index e84312624..000000000 --- a/src/libxinevdec/image.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2003-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * a image video decoder - */ - - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "image_video_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#ifdef PACKAGE_NAME -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_VERSION -#endif - -#include -#include -#include -#include -#include "bswap.h" - -typedef struct { - video_decoder_class_t decoder_class; - - /* - * private variables - */ - -} image_class_t; - - -typedef struct image_decoder_s { - video_decoder_t video_decoder; - - image_class_t *cls; - - xine_stream_t *stream; - int video_open; - - unsigned char *image; - int index; - -} image_decoder_t; - - -static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - if (!this->video_open) { - lprintf("opening video\n"); - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->video_open = 1; - } - - xine_buffer_copyin(this->image, this->index, buf->mem, buf->size); - this->index += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - int width, height, i; - MagickBooleanType status; - MagickWand *wand; - uint8_t *img_buf, *img_buf_ptr; - yuv_planes_t yuv_planes; - vo_frame_t *img; - - /* - * this->image -> rgb data - */ - wand = NewMagickWand(); - status = MagickReadImageBlob(wand, this->image, this->index); - this->index = 0; - - if (status == MagickFalse) { - DestroyMagickWand(wand); - lprintf("error loading image\n"); - return; - } - - width = MagickGetImageWidth(wand) & ~1; /* must be even for init_yuv_planes */ - height = MagickGetImageHeight(wand); - img_buf = malloc(width * height * 3); - MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); - DestroyMagickWand(wand); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); - - lprintf("image loaded successfully\n"); - - /* - * rgb data -> yuv_planes - */ - init_yuv_planes(&yuv_planes, width, height); - - img_buf_ptr = img_buf; - for (i=0; i < width*height; i++) { - uint8_t r = *(img_buf_ptr++); - uint8_t g = *(img_buf_ptr++); - uint8_t b = *(img_buf_ptr++); - - yuv_planes.y[i] = COMPUTE_Y(r, g, b); - yuv_planes.u[i] = COMPUTE_U(r, g, b); - yuv_planes.v[i] = COMPUTE_V(r, g, b); - } - free(img_buf); - - /* - * alloc and draw video frame - */ - img = this->stream->video_out->get_frame (this->stream->video_out, width, - height, (double)width/(double)height, - XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - img->pts = buf->pts; - img->duration = 3600; - img->bad_frame = 0; - - yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); - free_yuv_planes(&yuv_planes); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); - - img->draw(img, this->stream); - img->free(img); - } -} - - -static void image_flush (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * flush out any frames that are still stored in the decoder - */ -} - - -static void image_reset (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - - this->index = 0; -} - - -static void image_discontinuity (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ -} - -static void image_dispose (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - if (this->video_open) { - lprintf("closing video\n"); - - this->stream->video_out->close(this->stream->video_out, this->stream); - this->video_open = 0; - } - - xine_buffer_free(this->image); - - lprintf("closed\n"); - free (this); -} - - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, - xine_stream_t *stream) { - - image_class_t *cls = (image_class_t *) class_gen; - image_decoder_t *this; - - lprintf("opened\n"); - - this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); - - this->video_decoder.decode_data = image_decode_data; - this->video_decoder.flush = image_flush; - this->video_decoder.reset = image_reset; - this->video_decoder.discontinuity = image_discontinuity; - this->video_decoder.dispose = image_dispose; - this->cls = cls; - this->stream = stream; - - /* - * initialisation of privates - */ - - this->image = xine_buffer_init(10240); - - return &this->video_decoder; -} - -/* - * image plugin class - */ -static void *init_class (xine_t *xine, void *data) { - - image_class_t *this; - - this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "imagevdec"; - this->decoder_class.description = N_("image video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - /* - * initialisation of privates - */ - - lprintf("class opened\n"); - - return this; -} - -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, - 0 }; - -static const decoder_info_t dec_info_image = { - supported_types, /* supported types */ - 6 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "image", XINE_VERSION_CODE, &dec_info_image, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/rgb.c b/src/libxinevdec/rgb.c deleted file mode 100644 index 9c8409e5f..000000000 --- a/src/libxinevdec/rgb.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Raw RGB "Decoder" by Mike Melanson (melanson@pcisys.net) - * Actually, this decoder just converts a raw RGB image to a YUY2 map - * suitable for display under xine. - * - * This decoder deals with raw RGB data from Microsoft and Quicktime files. - * Data from a MS file can be 32-, 24-, 16-, or 8-bit. The latter can also - * be grayscale, depending on whether a palette is present. Data from a QT - * file can be 32-, 24-, 16-, 8-, 4-, 2-, or 1-bit. Any resolutions <= 8 - * can also be greyscale depending on what the QT file specifies. - * - * One more catch: Raw RGB from a Microsoft file is upside down. This is - * indicated by a negative height parameter. - */ - -#include -#include -#include -#include -#include - -#define LOG_MODULE "rgb" -#define LOG_VERBOSE -/* -#define LOG -*/ -#include -#include -#include -#include -#include "bswap.h" - -typedef struct { - video_decoder_class_t decoder_class; -} rgb_class_t; - -typedef struct rgb_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - rgb_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - double ratio; /* the width to height ratio */ - int bytes_per_pixel; - int bit_depth; - int upside_down; - - unsigned char yuv_palette[256 * 4]; - yuv_planes_t yuv_planes; - -} rgb_decoder_t; - -static void rgb_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - rgb_decoder_t *this = (rgb_decoder_t *) this_gen; - xine_bmiheader *bih; - palette_entry_t *palette; - int i; - int pixel_ptr, row_ptr; - int palette_index; - int buf_ptr; - unsigned int packed_pixel; - unsigned char r, g, b; - int pixels_left; - unsigned char pixel_byte = 0; - - vo_frame_t *img; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && - (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { - palette = (palette_entry_t *)buf->decoder_info_ptr[2]; - for (i = 0; i < buf->decoder_info[2]; i++) { - this->yuv_palette[i * 4 + 0] = - COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 1] = - COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 2] = - COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); - } - } - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - bih = (xine_bmiheader *) buf->content; - this->width = (bih->biWidth + 3) & ~0x03; - this->height = (bih->biHeight + 3) & ~0x03; - if (this->height < 0) { - this->upside_down = 1; - this->height = -this->height; - } else { - this->upside_down = 0; - } - this->ratio = (double)this->width/(double)this->height; - - this->bit_depth = bih->biBitCount; - if (this->bit_depth > 32) - this->bit_depth &= 0x1F; - /* round this number up in case of 15 */ - lprintf("width = %d, height = %d, bit_depth = %d\n", this->width, this->height, this->bit_depth); - - this->bytes_per_pixel = (this->bit_depth + 1) / 8; - - free (this->buf); - - /* minimal buffer size */ - this->bufsize = this->width * this->height * this->bytes_per_pixel; - this->buf = xine_xmalloc(this->bufsize); - this->size = 0; - - init_yuv_planes(&this->yuv_planes, this->width, this->height); - - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->decoder_ok = 1; - - /* load the stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw RGB"); - - return; - } else if (this->decoder_ok) { - - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - - - /* iterate through each row */ - buf_ptr = 0; - - if (this->upside_down) { - for (row_ptr = this->yuv_planes.row_width * (this->yuv_planes.row_count - 1); - row_ptr >= 0; row_ptr -= this->yuv_planes.row_width) { - for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { - - if (this->bytes_per_pixel == 1) { - - palette_index = this->buf[buf_ptr++]; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - } else if (this->bytes_per_pixel == 2) { - - /* ABGR1555 format, little-endian order */ - packed_pixel = _X_LE_16(&this->buf[buf_ptr]); - buf_ptr += 2; - UNPACK_BGR15(packed_pixel, r, g, b); - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } else { - - /* BGR24 or BGRA32 */ - b = this->buf[buf_ptr++]; - g = this->buf[buf_ptr++]; - r = this->buf[buf_ptr++]; - - /* the next line takes care of 'A' in the 32-bit case */ - buf_ptr += this->bytes_per_pixel - 3; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } - } - } - } else { - - for (row_ptr = 0; row_ptr < this->yuv_planes.row_width * this->yuv_planes.row_count; row_ptr += this->yuv_planes.row_width) { - pixels_left = 0; - for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { - - if (this->bit_depth == 1) { - - if (pixels_left == 0) { - pixels_left = 8; - pixel_byte = *this->buf++; - } - - if (pixel_byte & 0x80) { - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[1 * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[1 * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[1 * 4 + 2]; - } else { - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[0 * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[0 * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[0 * 4 + 2]; - } - pixels_left--; - pixel_byte <<= 1; - - } else if (this->bit_depth == 2) { - - if (pixels_left == 0) { - pixels_left = 4; - pixel_byte = *this->buf++; - } - - palette_index = (pixel_byte & 0xC0) >> 6; - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - pixels_left--; - pixel_byte <<= 2; - - } else if (this->bit_depth == 4) { - - if (pixels_left == 0) { - pixels_left = 2; - pixel_byte = *this->buf++; - } - - palette_index = (pixel_byte & 0xF0) >> 4; - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - pixels_left--; - pixel_byte <<= 4; - - } else if (this->bytes_per_pixel == 1) { - - palette_index = this->buf[buf_ptr++]; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - } else if (this->bytes_per_pixel == 2) { - - /* ARGB1555 format, big-endian order */ - packed_pixel = _X_BE_16(&this->buf[buf_ptr]); - buf_ptr += 2; - UNPACK_RGB15(packed_pixel, r, g, b); - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } else { - - /* RGB24 or ARGB32; the next line takes care of 'A' in the - * 32-bit case */ - buf_ptr += this->bytes_per_pixel - 3; - - r = this->buf[buf_ptr++]; - g = this->buf[buf_ptr++]; - b = this->buf[buf_ptr++]; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } - } - } - } - - yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); - - img->draw(img, this->stream); - img->free(img); - - this->size = 0; - } - } -} - -/* - * This function is called when xine needs to flush the system. Not - * sure when or if this is used or even if it needs to do anything. - */ -static void rgb_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void rgb_reset (video_decoder_t *this_gen) { - rgb_decoder_t *this = (rgb_decoder_t *) this_gen; - - this->size = 0; -} - -static void rgb_discontinuity (video_decoder_t *this_gen) { -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void rgb_dispose (video_decoder_t *this_gen) { - rgb_decoder_t *this = (rgb_decoder_t *) this_gen; - - free (this->buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - rgb_decoder_t *this ; - - this = (rgb_decoder_t *) xine_xmalloc (sizeof (rgb_decoder_t)); - - this->video_decoder.decode_data = rgb_decode_data; - this->video_decoder.flush = rgb_flush; - this->video_decoder.reset = rgb_reset; - this->video_decoder.discontinuity = rgb_discontinuity; - this->video_decoder.dispose = rgb_dispose; - this->size = 0; - - this->stream = stream; - this->class = (rgb_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - - return &this->video_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - rgb_class_t *this; - - this = (rgb_class_t *) xine_xmalloc (sizeof (rgb_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "RGB"; - this->decoder_class.description = N_("Raw RGB video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static const uint32_t video_types[] = { - BUF_VIDEO_RGB, - 0 - }; - -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "rgb", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/yuv.c b/src/libxinevdec/yuv.c deleted file mode 100644 index c1e5825c5..000000000 --- a/src/libxinevdec/yuv.c +++ /dev/null @@ -1,373 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * YUV "Decoder" by Mike Melanson (melanson@pcisys.net) - * Actually, this decoder just reorganizes chunks of raw YUV data in such - * a way that xine can display them. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#define VIDEOBUFSIZE 128*1024 - -typedef struct { - video_decoder_class_t decoder_class; -} yuv_class_t; - -typedef struct yuv_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - yuv_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - double ratio; /* the width to height ratio */ - - int progressive; - int top_field_first; - -} yuv_decoder_t; - -/************************************************************************** - * xine video plugin functions - *************************************************************************/ - -/* - * This function receives a buffer of data from the demuxer layer and - * figures out how to handle it based on its header flags. - */ -static void yuv_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - yuv_decoder_t *this = (yuv_decoder_t *) this_gen; - xine_bmiheader *bih; - - vo_frame_t *img; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - bih = (xine_bmiheader *) buf->content; - this->width = (bih->biWidth + 3) & ~0x03; - this->height = (bih->biHeight + 3) & ~0x03; - - if (buf->decoder_flags & BUF_FLAG_ASPECT) - this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; - else - this->ratio = (double)this->width / (double)this->height; - - this->progressive = buf->decoder_info[3]; - this->top_field_first = buf->decoder_info[4]; - - free (this->buf); - this->buf = NULL; - - this->bufsize = VIDEOBUFSIZE; - this->buf = malloc(this->bufsize); - this->size = 0; - - this->decoder_ok = 1; - - /* load the stream/meta info */ - switch (buf->type) { - - case BUF_VIDEO_YUY2: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YUY2"); - break; - - case BUF_VIDEO_YV12: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YV12"); - break; - - case BUF_VIDEO_YVU9: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YVU9"); - break; - - case BUF_VIDEO_GREY: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Greyscale YUV"); - break; - - case BUF_VIDEO_I420: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw I420"); - break; - - } - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); - - return; - } else if (this->decoder_ok && !(buf->decoder_flags & BUF_FLAG_SPECIAL)) { - uint8_t *src; - - /* if buffer contains an entire frame then there's no need to copy it - * into our internal buffer */ - if ((buf->decoder_flags & BUF_FLAG_FRAME_START) && - (buf->decoder_flags & BUF_FLAG_FRAME_END)) - src = buf->content; - else { - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - src = this->buf; - } - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - if (buf->type == BUF_VIDEO_YUY2) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); - - yuy2_to_yuy2( - /* src */ - src, this->width*2, - /* dst */ - img->base[0], img->pitches[0], - /* width x height */ - this->width, this->height); - - } else if (buf->type == BUF_VIDEO_YV12) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - yv12_to_yv12( - /* Y */ - src, this->width, - img->base[0], img->pitches[0], - /* U */ - src + (this->width * this->height * 5/4), this->width/2, - img->base[1], img->pitches[1], - /* V */ - src + (this->width * this->height), this->width/2, - img->base[2], img->pitches[2], - /* width x height */ - this->width, this->height); - - } else if (buf->type == BUF_VIDEO_I420) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - yv12_to_yv12( - /* Y */ - src, this->width, - img->base[0], img->pitches[0], - /* U */ - src + (this->width * this->height), this->width/2, - img->base[1], img->pitches[1], - /* V */ - src + (this->width * this->height * 5/4), this->width/2, - img->base[2], img->pitches[2], - /* width x height */ - this->width, this->height); - - } else if (buf->type == BUF_VIDEO_YVU9) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - - yuv9_to_yv12( - /* Y */ - src, - this->width, - img->base[0], - img->pitches[0], - /* U */ - src + (this->width * this->height), - this->width / 4, - img->base[1], - img->pitches[1], - /* V */ - src + (this->width * this->height) + - (this->width * this->height / 16), - this->width / 4, - img->base[2], - img->pitches[2], - /* width x height */ - this->width, - this->height); - - } else if (buf->type == BUF_VIDEO_GREY) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - xine_fast_memcpy(img->base[0], src, this->width * this->height); - memset( img->base[1], 0x80, this->width * this->height / 4 ); - memset( img->base[2], 0x80, this->width * this->height / 4 ); - - } else { - - /* just allocate something to avoid compiler warnings */ - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - } - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - - img->draw(img, this->stream); - img->free(img); - - this->size = 0; - } - } -} - -/* - * This function is called when xine needs to flush the system. Not - * sure when or if this is used or even if it needs to do anything. - */ -static void yuv_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void yuv_reset (video_decoder_t *this_gen) { - yuv_decoder_t *this = (yuv_decoder_t *) this_gen; - - this->size = 0; -} - -static void yuv_discontinuity (video_decoder_t *this_gen) { -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void yuv_dispose (video_decoder_t *this_gen) { - yuv_decoder_t *this = (yuv_decoder_t *) this_gen; - - free (this->buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - yuv_decoder_t *this ; - - this = (yuv_decoder_t *) xine_xmalloc (sizeof (yuv_decoder_t)); - - this->video_decoder.decode_data = yuv_decode_data; - this->video_decoder.flush = yuv_flush; - this->video_decoder.reset = yuv_reset; - this->video_decoder.discontinuity = yuv_discontinuity; - this->video_decoder.dispose = yuv_dispose; - this->size = 0; - - this->stream = stream; - this->class = (yuv_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - - return &this->video_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - yuv_class_t *this; - - this = (yuv_class_t *) xine_xmalloc (sizeof (yuv_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "YUV"; - this->decoder_class.description = N_("Raw YUV video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static const uint32_t video_types[] = { - BUF_VIDEO_YUY2, - BUF_VIDEO_YV12, - BUF_VIDEO_YVU9, - BUF_VIDEO_GREY, - BUF_VIDEO_I420, - 0 - }; - -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "yuv", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/video_dec/Makefile.am b/src/video_dec/Makefile.am new file mode 100644 index 000000000..321d70c1f --- /dev/null +++ b/src/video_dec/Makefile.am @@ -0,0 +1,38 @@ +include $(top_srcdir)/misc/Makefile.common + +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) +AM_LDFLAGS = $(xineplug_ldflags) + +EXTRA_DIST = foovideo.c + +if ENABLE_IMAGEMAGICK +image_module = xineplug_decode_image.la +endif + +if ENABLE_GDK_PIXBUF +gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la +endif + +xineplug_LTLIBRARIES = $(image_module) \ + $(gdkpixbuf_module) \ + $(theora_module) \ + xineplug_decode_bitplane.la \ + xineplug_decode_rgb.la \ + xineplug_decode_yuv.la + +xineplug_decode_bitplane_la_SOURCES = bitplane.c +xineplug_decode_bitplane_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) + +xineplug_decode_rgb_la_SOURCES = rgb.c +xineplug_decode_rgb_la_LIBADD = $(XINE_LIB) + +xineplug_decode_yuv_la_SOURCES = yuv.c +xineplug_decode_yuv_la_LIBADD = $(XINE_LIB) + +xineplug_decode_image_la_SOURCES = image.c +xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(WAND_LIBS) +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) diff --git a/src/video_dec/bitplane.c b/src/video_dec/bitplane.c new file mode 100644 index 000000000..327e14aee --- /dev/null +++ b/src/video_dec/bitplane.c @@ -0,0 +1,1554 @@ +/* + * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Bitplane "Decoder" by Manfred Tremmel (Manfred.Tremmel@iiv.de) + * Converts Amiga typical bitplane pictures to a YUV2 map + * suitable for display under xine. It's based on the rgb-decoder + * and the development documentation from the Amiga Developer CD + * + * Supported formats: + * - uncompressed and byterun1 compressed ILBM data + * - IFF ANIM compression methods OPT 5, 7 (long and short) and + * 8 (long and short) + * - untested (found no testfiles) IFF-ANIM OPT 3, 4 and 6 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#include "demuxers/iff.h" + +#define IFF_REPLACE_BYTE_SIMPLE(ptr, old_data, new_data, colorindexx ) { \ + register uint8_t *index_ptr = ptr; \ + register uint8_t colorindex = colorindexx; \ + *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x80) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x40) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x20) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x10) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x08) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x04) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x02) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ + old_data = new_data; \ +} + +#define IFF_REPLACE_BYTE(ptr, yuvy, yuvu, yuvv, yuv_palette, old_data, new_data, colorindexx ) { \ + register uint8_t *index_ptr = ptr; \ + register uint8_t colorindex = colorindexx; \ + register uint8_t *yuv_y = yuvy; \ + register uint8_t *yuv_u = yuvu; \ + register uint8_t *yuv_v = yuvv; \ + *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x80) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x40) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x20) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x10) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x08) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x04) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x02) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ + yuv_index = *index_ptr * 4; \ + *yuv_y = yuv_palette[yuv_index++]; \ + *yuv_u = yuv_palette[yuv_index++]; \ + *yuv_v = yuv_palette[yuv_index]; \ + old_data = new_data; \ +} + +#define IFF_REPLACE_SHORT_SIMPLE(ptr_s, old_data_s, new_data_s, colorindexx_s ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ + uint8_t *xold_data = (uint8_t *)old_data_s; \ + uint8_t *xnew_data = (uint8_t *)new_data_s; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ +} + +#define IFF_REPLACE_SHORT(ptr_s, yuvy_s, yuvu_s, yuvv_s, yuv_palette_s, old_data_s, new_data_s, colorindexx_s ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ + uint8_t *xold_data = (uint8_t *)old_data_s; \ + uint8_t *xnew_data = (uint8_t *)new_data_s; \ + uint8_t *xyuv_y = yuvy_s; \ + uint8_t *xyuv_u = yuvu_s; \ + uint8_t *xyuv_v = yuvv_s; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ +} + +#define IFF_REPLACE_LONG_SIMPLE(ptr_l, old_data_l, new_data_l, colorindexx_l ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ + uint8_t *xold_data = (uint8_t *)old_data_l; \ + uint8_t *xnew_data = (uint8_t *)new_data_l; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ +} + +#define IFF_REPLACE_LONG(ptr_l, yuvy_l, yuvu_l, yuvv_l, yuv_palette_l, old_data_l, new_data_l, colorindexx_l ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ + uint8_t *xold_data = (uint8_t *)old_data_l; \ + uint8_t *xnew_data = (uint8_t *)new_data_l; \ + uint8_t *xyuv_y = yuvy_l; \ + uint8_t *xyuv_u = yuvu_l; \ + uint8_t *xyuv_v = yuvv_l; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ +} + +typedef struct { + video_decoder_class_t decoder_class; +} bitplane_class_t; + +typedef struct bitplane_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + bitplane_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; /* 0 = draw picture, 1 = skip it */ + int framenumber; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + int size_uk; /* size of unkompressed bitplane */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + int num_pixel; /* number pixel */ + double ratio; /* the width to height ratio */ + int bytes_per_pixel; + int num_bitplanes; + int camg_mode; + int is_ham; + + unsigned char yuv_palette[256 * 4]; + unsigned char rgb_palette[256 * 4]; + yuv_planes_t yuv_planes; + yuv_planes_t yuv_planes_hist; + + uint8_t *buf_uk; /* uncompressed buffer */ + uint8_t *buf_uk_hist; /* uncompressed buffer historic */ + uint8_t *index_buf; /* index buffer (for indexed pics) */ + uint8_t *index_buf_hist;/* index buffer historic */ + +} bitplane_decoder_t; + +/* create a new buffer and decde a byterun1 decoded buffer into it */ +static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed, + int size_compressed, + int size_uncompressed) { + + /* BytRun1 decompression */ + int pixel_ptr = 0; + int i = 0; + int j = 0; + + uint8_t *uncompressed = xine_xmalloc( size_uncompressed ); + + while ( i < size_compressed && + pixel_ptr < size_uncompressed ) { + if( compressed[i] <= 127 ) { + j = compressed[i++]; + if( (i+j) > size_compressed ) { + free(uncompressed); + return NULL; + } + for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { + uncompressed[pixel_ptr++] = compressed[i++]; + } + } else if ( compressed[i] > 128 ) { + j = 256 - compressed[i++]; + if( i >= size_compressed ) { + free(uncompressed); + return NULL; + } + for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { + uncompressed[pixel_ptr++] = compressed[i]; + } + i++; + } + } + return uncompressed; +} + +/* create a new buffer with "normal" index or rgb numbers out of a bitplane */ +static void bitplane_decode_bitplane (uint8_t *bitplane_buffer, + uint8_t *index_buf, + int width, + int height, + int num_bitplanes, + int bytes_per_pixel ) { + + int rowsize = width / 8; + int pixel_ptr = 0; + int row_ptr = 0; + int palette_index = 0; + int i = 0; + int j = 0; + int row_i = 0; + int row_j = 0; + int palette_offset = 0; + int palette_index_rowsize = 0; + uint8_t color = 0; + uint8_t data = 0; + int bytes_per_pixel_8 = bytes_per_pixel * 8; + int rowsize_num_bitplanes = rowsize * num_bitplanes; + int width_bytes_per_pixel = width * bytes_per_pixel; + + for (i = 0; i < (height * width_bytes_per_pixel); index_buf[i++] = 0); + + /* decode Bitplanes to RGB/Index Numbers */ + for (row_ptr = 0; row_ptr < height; row_ptr++) { + + row_i = row_ptr * width_bytes_per_pixel; + row_j = row_ptr * rowsize_num_bitplanes; + + for (palette_index = 0; palette_index < num_bitplanes; palette_index++) { + + palette_offset = ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0); + color = bitplainoffeset[palette_index]; + palette_index_rowsize = palette_index * rowsize; + + for (pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + i = row_i + + (pixel_ptr * bytes_per_pixel_8) + + palette_offset; + j = row_j + palette_index_rowsize + pixel_ptr; + + data = bitplane_buffer[j]; + + index_buf[i] += ((data & 0x80) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x40) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x20) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x10) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x08) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x04) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x02) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x01) ? color : 0); + } + } + } +} + +/* create Buffer decode HAM6 and HAM8 to YUV color */ +static void bitplane_decode_ham (uint8_t *ham_buffer, + yuv_planes_t *yuv_planes, + int width, + int height, + int num_bitplanes, + int bytes_per_pixel, + unsigned char *rgb_palette ) { + + uint8_t *ham_buffer_work = ham_buffer; + uint8_t *ham_buffer_end = &ham_buffer[(width * height)]; + uint8_t *yuv_ptr_y = yuv_planes->y; + uint8_t *yuv_ptr_u = yuv_planes->u; + uint8_t *yuv_ptr_v = yuv_planes->v; + int i = 0; + int j = 0; + uint8_t r = 0; + uint8_t g = 0; + uint8_t b = 0; + /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */ + int hambits = num_bitplanes > 6 ? 6 : 4; + /* the other bits contain the real data, dreate a mask out of it */ + int maskbits = 8 - hambits; + int mask = ( 1 << hambits ) - 1; + + for(; ham_buffer_work < ham_buffer_end; j = *ham_buffer_work++) { + i = (j & mask); + switch ( j >> hambits ) { + case HAMBITS_CMAP: + /* Take colors from palette */ + r = rgb_palette[i * 4 + 0]; + g = rgb_palette[i * 4 + 1]; + b = rgb_palette[i * 4 + 2]; + break; + case HAMBITS_BLUE: + /* keep red and green and modify blue */ + b = i << maskbits; + b |= b >> hambits; + break; + case HAMBITS_RED: + /* keep green and blue and modify red */ + r = i << maskbits; + r |= r >> hambits; + break; + case HAMBITS_GREEN: + /* keep red and blue and modify green */ + g = i << maskbits; + g |= g >> hambits; + break; + default: + break; + } + *yuv_ptr_y++ = COMPUTE_Y(r, g, b); + *yuv_ptr_u++ = COMPUTE_U(r, g, b); + *yuv_ptr_v++ = COMPUTE_V(r, g, b); + } +} + +/* decoding method 3 */ +static void bitplane_sdelta_opt_3 (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t palette_index = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint16_t *ptr = NULL; + uint16_t *planeptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint16_t *rowworkptr = NULL; + int16_t s = 0; + int16_t size = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t yuv_index = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); + if( data != (uint16_t *)this->buf ) { + /* This 8 Pointers are followd by another 8 */ + ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); + + /* in this case, I think big/little endian is not important ;-) */ + while( *data != 0xFFFF) { + row_ptr = 0; + size = _X_BE_16(data); + data++; + if( size >= 0 ) { + rowworkptr = planeptr + size; + pixel_ptr_bit = size * 16; + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], + &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], + &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + } else { + size = 0 - size + 2; + rowworkptr = planeptr + size; + pixel_ptr_bit = size * 16; + s = _X_BE_16(data); + data++; + while( s--) { + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], + &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], + &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr++; + data++; + } + } + + + + + size = _X_BE_16(ptr); + ptr++; + if (size < 0) { + for (s = size; s < 0; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } + else { + for (s = 0; s < size; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } + } + } + } +} + +/* decoding method 4 */ +static void bitplane_set_dlta_short (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t palette_index = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint16_t *ptr = NULL; + uint16_t *planeptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint16_t *rowworkptr = NULL; + int16_t s = 0; + int16_t size = 0; + uint16_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t yuv_index = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); + if( data != (uint16_t *)this->buf ) { + /* This 8 Pointers are followd by another 8 */ + ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); + + /* in this case, I think big/little endian is not important ;-) */ + while( *ptr != 0xFFFF) { + pixel_ptr = _X_BE_16(ptr); + pixel_ptr_bit = pixel_ptr * 16; + row_ptr = 0; + rowworkptr = planeptr + pixel_ptr; + ptr++; + size = _X_BE_16(ptr); + ptr++; + if (size < 0) { + for (s = size; s < 0; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + for (s = 0; s < size; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } + } + } + } +} + +/* decoding method 5 */ +static void bitplane_dlta_5 (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 8; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t delta_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint8_t *planeptr = NULL; + uint8_t *rowworkptr = NULL; + uint8_t *picture_end = this->buf_uk + (rowsize_all_planes * this->height); + uint8_t *data = NULL; + uint8_t *data_end = this->buf + this->size; + uint8_t op_count = 0; + uint8_t op = 0; + uint8_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = &this->buf_uk[(palette_index * rowsize)]; + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + delta_offset = _X_BE_32(&deltadata[palette_index]); + + if (delta_offset > 0) { + data = this->buf + delta_offset; + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = planeptr + pixel_ptr; + pixel_ptr_bit = pixel_ptr * 8; + row_ptr = 0; + /* execute ops */ + for( op_count = *data++; op_count; op_count--) { + op = *data++; + if (op & 0x80) { + /* Uniq ops */ + count = op & 0x7f; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_BYTE( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = *data++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_BYTE( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 7 (short version) */ +static void bitplane_dlta_7_short (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t opcode_offset = 0; + uint32_t data_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint8_t *planeptr = NULL; + uint16_t *rowworkptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint8_t *op_ptr = NULL; + uint8_t op_count = 0; + uint8_t op = 0; + uint8_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = &this->buf_uk[(palette_index * rowsize * 2)]; + /* find opcode and data offset (up to 8 pointers, one for every bitplane */ + opcode_offset = _X_BE_32(&deltadata[palette_index]); + data_offset = _X_BE_32(&deltadata[palette_index + 8]); + + if (opcode_offset > 0 && data_offset > 0) { + data = (uint16_t *)(&this->buf[data_offset]); + op_ptr = this->buf + opcode_offset; + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = (uint16_t *)(&planeptr[pixel_ptr * 2]); + pixel_ptr_bit = pixel_ptr * 16; + row_ptr = 0; + /* execute ops */ + for( op_count = *op_ptr++; op_count; op_count--) { + op = *op_ptr++; + if (op & 0x80) { + /* Uniq ops */ + count = op & 0x7f; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = *op_ptr++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 7 (long version) */ +static void bitplane_dlta_7_long (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 32; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t opcode_offset = 0; + uint32_t data_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint8_t *planeptr = NULL; + uint32_t *rowworkptr = NULL; + uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); + uint32_t *data = NULL; + uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); + uint8_t *op_ptr = NULL; + uint8_t op_count = 0; + uint8_t op = 0; + uint8_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + planeptr = &this->buf_uk[(palette_index * rowsize * 4)]; + /* find opcode and data offset (up to 8 pointers, one for every bitplane */ + opcode_offset = _X_BE_32(&deltadata[palette_index]); + data_offset = _X_BE_32(&deltadata[palette_index + 8]); + + if (opcode_offset > 0 && data_offset > 0) { + data = (uint32_t *)(&this->buf[data_offset]); + op_ptr = this->buf + opcode_offset; + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = (uint32_t *)(&planeptr[pixel_ptr * 4]); + pixel_ptr_bit = pixel_ptr * 32; + row_ptr = 0; + /* execute ops */ + for( op_count = *op_ptr++; op_count; op_count--) { + op = *op_ptr++; + if (op & 0x80) { + /* Uniq ops */ + count = op & 0x7f; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = *op_ptr++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 8 short */ +static void bitplane_dlta_8_short (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t delta_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t row_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint16_t *planeptr = NULL; + uint16_t *rowworkptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint16_t op_count = 0; + uint16_t op = 0; + uint16_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + delta_offset = _X_BE_32(&deltadata[palette_index]); + + if (delta_offset > 0) { + data = (uint16_t *)(&this->buf[delta_offset]); + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = planeptr + pixel_ptr; + pixel_ptr_bit = pixel_ptr * 16; + row_ptr = 0; + /* execute ops */ + op_count = _X_BE_16(data); + data++; + for( ; op_count; op_count--) { + op = _X_BE_16(data); + data++; + if (op & 0x8000) { + /* Uniq ops */ + count = op & 0x7fff; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = _X_BE_16(data); + data++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 8 long */ +static void bitplane_dlta_8_long (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 32; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t delta_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint32_t *planeptr = NULL; + uint32_t *rowworkptr = NULL; + uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); + uint32_t *data = NULL; + uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); + uint32_t op_count = 0; + uint32_t op = 0; + uint32_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint32_t *)(&this->buf_uk[(palette_index * rowsize * 4)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + delta_offset = _X_BE_32(&deltadata[palette_index]); + + if (delta_offset > 0) { + data = (uint32_t *)(&this->buf[delta_offset]); + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = planeptr + pixel_ptr; + pixel_ptr_bit = pixel_ptr * 32; + row_ptr = 0; + /* execute ops */ + op_count = _X_BE_32(data); + data++; + for( ; op_count; op_count--) { + op = _X_BE_32(data); + data++; + if (op & 0x80000000) { + /* Uniq ops */ + count = op & 0x7fffffff; /* get count */ + while(count--) { + if (data <= data_end || rowworkptr <= picture_end) { + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[((row_ptr * this->width) + pixel_ptr_bit)], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = _X_BE_32(data); + data++; + while(count--) { + if (data <= data_end && rowworkptr <= picture_end) { + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +/* bitplane_decode_bitplane(this->buf_uk, this->index_buf, this->width, this->height, this->num_bitplanes, 1);*/ +} + +static void bitplane_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; + xine_bmiheader *bih = 0; + palette_entry_t *palette = 0; + AnimHeader *anhd = NULL; + int i = 0; + int j = 0; + int buf_ptr = 0; + unsigned char r = 0; + unsigned char g = 0; + unsigned char b = 0; + uint8_t *buf_exchange = NULL; + + vo_frame_t *img = 0; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && + (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { + palette = (palette_entry_t *)buf->decoder_info_ptr[2]; + + for (i = 0; i < buf->decoder_info[2]; i++) { + this->yuv_palette[i * 4 + 0] = + COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 1] = + COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 2] = + COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); + this->rgb_palette[i * 4 + 0] = palette[i].r; + this->rgb_palette[i * 4 + 1] = palette[i].g; + this->rgb_palette[i * 4 + 2] = palette[i].b; + } + + /* EHB Pictures not allways contain all 64 colors, sometimes only */ + /* the first 32 are included and sometimes all 64 colors are provide,*/ + /* but second 32 are only stupid dirt, so recalculate them */ + if (((this->num_bitplanes == 6) && + (buf->decoder_info[2] == 32)) || + (this->camg_mode & CAMG_EHB)) { + for (i = 32; i < 64; i++) { + this->rgb_palette[i * 4 + 0] = palette[(i-32)].r / 2; + this->rgb_palette[i * 4 + 1] = palette[(i-32)].g / 2; + this->rgb_palette[i * 4 + 2] = palette[(i-32)].b / 2; + this->yuv_palette[i * 4 + 0] = + COMPUTE_Y(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); + this->yuv_palette[i * 4 + 1] = + COMPUTE_U(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); + this->yuv_palette[i * 4 + 2] = + COMPUTE_V(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); + } + } + + return; + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + bih = (xine_bmiheader *) buf->content; + this->width = (bih->biWidth + 15) & ~0x0f; + this->height = bih->biHeight; + this->num_pixel = this->width * this->height; + this->ratio = (double)this->width/(double)this->height; + this->video_step = buf->decoder_info[1]; + /* Palette based Formates use up to 8 Bit per pixel, always use 8 Bit if less */ + this->bytes_per_pixel = (bih->biBitCount + 1) / 8; + if( this->bytes_per_pixel < 1 ) + this->bytes_per_pixel = 1; + + /* New Buffer for indexes (palette based formats) */ + this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + + this->num_bitplanes = bih->biPlanes; + this->camg_mode = bih->biCompression; + if( this->camg_mode & CAMG_HAM ) + this->is_ham = 1; + else + this->is_ham = 0; + + if( buf->decoder_info[2] != buf->decoder_info[3] && + buf->decoder_info[3] > 0 ) { + this->ratio *= buf->decoder_info[2]; + this->ratio /= buf->decoder_info[3]; + } + + if( (bih->biCompression & CAMG_HIRES) && + !(bih->biCompression & CAMG_LACE) ) { + if( (buf->decoder_info[2] * 16) > (buf->decoder_info[3] * 10) ) + this->ratio /= 2.0; + } + + if( !(bih->biCompression & CAMG_HIRES) && + (bih->biCompression & CAMG_LACE) ) { + if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 16) ) + this->ratio *= 2.0; + } + + free (this->buf); + this->bufsize = VIDEOBUFSIZE; + this->buf = xine_xmalloc(this->bufsize); + this->size = 0; + this->framenumber = 0; + + init_yuv_planes(&this->yuv_planes, this->width, this->height); + init_yuv_planes(&this->yuv_planes_hist, this->width, this->height); + + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->decoder_ok = 1; + + /* load the stream/meta info */ + switch( buf->type ) { + case BUF_VIDEO_BITPLANE: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Uncompressed bitplane"); + break; + case BUF_VIDEO_BITPLANE_BR1: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ByteRun1 bitplane"); + break; + default: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Unknown bitplane"); + break; + } + + return; + } else if (this->decoder_ok) { + + this->skipframes = 0; + this->framenumber++; + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) + this->video_step = buf->decoder_info[0]; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + anhd = (AnimHeader *)(buf->decoder_info_ptr[0]); + + if( (this->buf_uk == NULL) || + (anhd == NULL) || + (anhd->operation == IFF_ANHD_ILBM) ) { + + /* iterate through each row */ + buf_ptr = 0; + this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); + + if( this->buf_uk_hist != NULL ) + xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); + switch( buf->type ) { + case BUF_VIDEO_BITPLANE: + /* uncompressed Buffer, set decoded_buf pointer direct to input stream */ + if( this->buf_uk == NULL ) + this->buf_uk = xine_xmalloc( (this->size) ); + xine_fast_memcpy (this->buf_uk, this->buf, this->size); + break; + case BUF_VIDEO_BITPLANE_BR1: + /* create Buffer for decompressed bitmap */ + this->buf_uk = bitplane_decode_byterun1( + this->buf, /* compressed buffer */ + this->size, /* size of compressed data */ + this->size_uk ); /* size of uncompressed data */ + + if( this->buf_uk == NULL ) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: error doing ByteRun1 decompression\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + } + /* set pointer to decompressed Buffer */ + break; + default: + break; + } + bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */ + this->index_buf, /* index buffer */ + this->width, /* width */ + this->height, /* hight */ + this->num_bitplanes, /* number bitplanes */ + this->bytes_per_pixel); /* used Bytes per pixel */ + + if ((this->bytes_per_pixel == 1) && + (this->is_ham == 0) ) { + buf_exchange = this->index_buf; + for (i = 0; i < (this->height * this->width); i++) { + j = *buf_exchange++ * 4; + this->yuv_planes.y[i] = this->yuv_palette[j++]; + this->yuv_planes.u[i] = this->yuv_palette[j++]; + this->yuv_planes.v[i] = this->yuv_palette[j]; + } + } + if( this->buf_uk_hist == NULL ) { + this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); + xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); + xine_fast_memcpy (this->index_buf_hist, this->index_buf, + (this->num_pixel * this->bytes_per_pixel)); + xine_fast_memcpy (this->yuv_planes_hist.y, this->yuv_planes.y, (this->num_pixel)); + xine_fast_memcpy (this->yuv_planes_hist.u, this->yuv_planes.u, (this->num_pixel)); + xine_fast_memcpy (this->yuv_planes_hist.v, this->yuv_planes.v, (this->num_pixel)); + } + } else { + /* when no start-picture is given, create a empty one */ + if( this->buf_uk_hist == NULL ) { + this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); + this->buf_uk = xine_xmalloc( (this->size_uk) ); + this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); + for (i = 0; i < this->size_uk; i++) { + this->buf_uk[i] = 0; + this->buf_uk_hist[i] = 0; + } + } + if( this->index_buf == NULL ) { + this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + for (i = 0; i < (this->num_pixel * this->bytes_per_pixel); i++) { + this->index_buf[i] = 0; + this->index_buf_hist[i] = 0; + } + } + + switch( anhd->operation ) { + /* also known as IFF-ANIM OPT1 (never seen in real world) */ + case IFF_ANHD_XOR: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: Anim Opt 1 is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + /* also known as IFF-ANIM OPT2 (never seen in real world) */ + case IFF_ANHD_LDELTA: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: Anim Opt 2 is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + /* also known as IFF-ANIM OPT3 */ + case IFF_ANHD_SDELTA: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT3"); + bitplane_sdelta_opt_3 ( this ); + return; + break; + /* also known as IFF-ANIM OPT4 (never seen in real world) */ + case IFF_ANHD_SLDELTA: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT4 (SLDELTA)"); + bitplane_set_dlta_short ( this ); + break; + /* also known as IFF-ANIM OPT5 */ + case IFF_ANHD_BVDELTA: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT5 (BVDELTA)"); + bitplane_dlta_5(this); + break; + /* IFF-ANIM OPT6 is exactly the same as OPT5, but for stereo-displays */ + /* first picture is on the left display, second on the right, third on */ + /* the left, forth on right, ... Only display left picture on mono display*/ + case IFF_ANHD_STEREOO5: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT6 (BVDELTA STEREO)"); + bitplane_dlta_5(this); + if( this->framenumber % 2 == 0 ) + this->skipframes = 1; + return; + break; + case IFF_ANHD_OPT7: + if(anhd->bits == 0) { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (SHORT)"); + bitplane_dlta_7_short(this); + } else { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (LONG)"); + bitplane_dlta_7_long(this); + } + break; + case IFF_ANHD_OPT8: + if(anhd->bits == 0) { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (SHORT)"); + bitplane_dlta_8_short(this); + } else { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (LONG)"); + bitplane_dlta_8_long(this); + } + break; + case IFF_ANHD_ASCIIJ: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: Anim ASCIIJ is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + default: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: This anim-type is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + } + /* change old bitmap buffer (which now is the new one) with new buffer */ + buf_exchange = this->buf_uk; + this->buf_uk = this->buf_uk_hist; + this->buf_uk_hist = buf_exchange; + /* do the same with the index buffer */ + buf_exchange = this->index_buf; + this->index_buf = this->index_buf_hist; + this->index_buf_hist = buf_exchange; + /* and also with yuv buffer */ + buf_exchange = this->yuv_planes.y; + this->yuv_planes.y = this->yuv_planes_hist.y; + this->yuv_planes_hist.y = buf_exchange; + buf_exchange = this->yuv_planes.u; + this->yuv_planes.u = this->yuv_planes_hist.u; + this->yuv_planes_hist.u = buf_exchange; + buf_exchange = this->yuv_planes.v; + this->yuv_planes.v = this->yuv_planes_hist.v; + this->yuv_planes_hist.v = buf_exchange; + } + + if( this->skipframes == 0 ) { + switch (this->bytes_per_pixel) { + case 1: + /* HAM-pictrues need special handling */ + if( this->is_ham ) { + /* Decode HAM-Pictures to YUV */ + bitplane_decode_ham( this->index_buf, /* HAM-bitplane buffer */ + &(this->yuv_planes), /* YUV buffer */ + this->width, /* width */ + this->height, /* hight */ + this->num_bitplanes, /* number bitplanes */ + this->bytes_per_pixel, /* used Bytes per pixel */ + this->rgb_palette); /* Palette (RGB) */ + } + break; + case 3: + buf_exchange = this->index_buf; + for (i = 0; i < (this->height * this->width); i++) { + r = *buf_exchange++; + g = *buf_exchange++; + b = *buf_exchange++; + + this->yuv_planes.y[i] = COMPUTE_Y(r, g, b); + this->yuv_planes.u[i] = COMPUTE_U(r, g, b); + this->yuv_planes.v[i] = COMPUTE_V(r, g, b); + } + break; + default: + break; + } + + yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); + + img->draw(img, this->stream); + } + img->free(img); + + this->size = 0; + if ( buf->decoder_info[1] > 90000 ) + xine_usec_sleep(buf->decoder_info[1]); + } + } +} + +/* + * This function is called when xine needs to flush the system. Not + * sure when or if this is used or even if it needs to do anything. + */ +static void bitplane_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void bitplane_reset (video_decoder_t *this_gen) { + bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; + + this->size = 0; +} + +static void bitplane_discontinuity (video_decoder_t *this_gen) { +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void bitplane_dispose (video_decoder_t *this_gen) { + bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; + + free (this->buf); + free (this->buf_uk); + free (this->buf_uk_hist); + free (this->index_buf); + free (this->index_buf_hist); + free (this->index_buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + bitplane_decoder_t *this = (bitplane_decoder_t *) xine_xmalloc (sizeof (bitplane_decoder_t)); + + this->video_decoder.decode_data = bitplane_decode_data; + this->video_decoder.flush = bitplane_flush; + this->video_decoder.reset = bitplane_reset; + this->video_decoder.discontinuity = bitplane_discontinuity; + this->video_decoder.dispose = bitplane_dispose; + this->size = 0; + + this->stream = stream; + this->class = (bitplane_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + this->buf_uk = NULL; + this->index_buf = NULL; + this->index_buf = NULL; + + return &this->video_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + bitplane_class_t *this = (bitplane_class_t *) xine_xmalloc (sizeof (bitplane_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "bitplane"; + this->decoder_class.description = N_("Raw bitplane video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static const uint32_t video_types[] = { + BUF_VIDEO_BITPLANE, + BUF_VIDEO_BITPLANE_BR1, + 0 +}; + +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "bitplane", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/foovideo.c b/src/video_dec/foovideo.c new file mode 100644 index 000000000..49c63422c --- /dev/null +++ b/src/video_dec/foovideo.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * foovideo.c: This is a reference video decoder for the xine multimedia + * player. It really works too! It will output frames of packed YUY2 data + * where each byte in the map is the same value, which is 3 larger than the + * value from the last frame. This creates a slowly rotating solid color + * frame when the frames are played in succession. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#define VIDEOBUFSIZE 128*1024 + +typedef struct { + video_decoder_class_t decoder_class; +} foovideo_class_t; + +typedef struct foovideo_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + foovideo_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + double ratio; /* the width to height ratio */ + + /* these are variables exclusive to the foo video decoder */ + unsigned char current_yuv_byte; + +} foovideo_decoder_t; + +/************************************************************************** + * foovideo specific decode functions + *************************************************************************/ + +/************************************************************************** + * xine video plugin functions + *************************************************************************/ + +/* + * This function receives a buffer of data from the demuxer layer and + * figures out how to handle it based on its header flags. + */ +static void foovideo_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + xine_bmiheader *bih; + + vo_frame_t *img; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + free(this->buf); + + bih = (xine_bmiheader *) buf->content; + this->width = bih->biWidth; + this->height = bih->biHeight; + this->ratio = (double)this->width/(double)this->height; + + if (this->buf) + free (this->buf); + this->bufsize = VIDEOBUFSIZE; + this->buf = malloc(this->bufsize); + this->size = 0; + + /* take this opportunity to load the stream/meta info */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "foovideo"); + + /* do anything else relating to initializing this decoder */ + this->current_yuv_byte = 0; + + this->decoder_ok = 1; + + return; + } else if (this->decoder_ok) { + + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, + XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + + memset(img->base[0], this->current_yuv_byte, + this->width * this->height * 2); + this->current_yuv_byte += 3; + + img->draw(img, this->stream); + img->free(img); + + this->size = 0; + } + } +} + +/* + * This function is called when xine needs to flush the system. + */ +static void foovideo_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void foovideo_reset (video_decoder_t *this_gen) { + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + + this->size = 0; +} + +/* + * The decoder should forget any stored pts values here. + */ +static void foovideo_discontinuity (video_decoder_t *this_gen) { + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void foovideo_dispose (video_decoder_t *this_gen) { + + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + + free (this->buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +/* + * This function allocates, initializes, and returns a private video + * decoder structure. + */ +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + foovideo_decoder_t *this ; + + this = (foovideo_decoder_t *) xine_xmalloc (sizeof (foovideo_decoder_t)); + + this->video_decoder.decode_data = foovideo_decode_data; + this->video_decoder.flush = foovideo_flush; + this->video_decoder.reset = foovideo_reset; + this->video_decoder.discontinuity = foovideo_discontinuity; + this->video_decoder.dispose = foovideo_dispose; + this->size = 0; + + this->stream = stream; + this->class = (foovideo_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + + return &this->video_decoder; +} + +/* + * This function frees the video decoder class and any other memory that was + * allocated. + */ +static void dispose_class (video_decoder_class_t *this) { + free (this); +} + +/* + * This function allocates a private video decoder class and initializes + * the class's member functions. + */ +static void *init_plugin (xine_t *xine, void *data) { + + foovideo_class_t *this; + + this = (foovideo_class_t *) xine_xmalloc (sizeof (foovideo_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "foovideo"; + this->decoder_class.description = N_("foovideo: reference xine video decoder plugin"); + this->decoder_class.dispose = dispose_class; + + return this; +} + +/* + * This is a list of all of the internal xine video buffer types that + * this decoder is able to handle. Check src/xine-engine/buffer.h for a + * list of valid buffer types (and add a new one if the one you need does + * not exist). Terminate the list with a 0. + */ +static const uint32_t video_types[] = { + /* BUF_VIDEO_FOOVIDEO, */ + BUF_VIDEO_VQA, + BUF_VIDEO_SORENSON_V3, + 0 +}; + +/* + * This data structure combines the list of supported xine buffer types and + * the priority that the plugin should be given with respect to other + * plugins that handle the same buffer type. A plugin with priority (n+1) + * will be used instead of a plugin with priority (n). + */ +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 5 /* priority */ +}; + +/* + * The plugin catalog entry. This is the only information that this plugin + * will export to the public. + */ +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* { type, API, "name", version, special_info, init_function } */ + { PLUGIN_VIDEO_DECODER, 19, "foovideo", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/gdkpixbuf.c b/src/video_dec/gdkpixbuf.c new file mode 100644 index 000000000..28c9c77c7 --- /dev/null +++ b/src/video_dec/gdkpixbuf.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * a gdk-pixbuf-based image video decoder + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "gdkpixbuf_video_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include +#include "bswap.h" + +#include + +typedef struct { + video_decoder_class_t decoder_class; + + /* + * private variables + */ + +} image_class_t; + + +typedef struct image_decoder_s { + video_decoder_t video_decoder; + + image_class_t *cls; + + xine_stream_t *stream; + int video_open; + + GdkPixbufLoader *loader; + +} image_decoder_t; + + +static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + image_decoder_t *this = (image_decoder_t *) this_gen; + GError *error = NULL; + + if (!this->video_open) { + lprintf("opening video\n"); + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->video_open = 1; + } + + if (this->loader == NULL) { + this->loader = gdk_pixbuf_loader_new (); + } + + if (gdk_pixbuf_loader_write (this->loader, buf->mem, buf->size, &error) == FALSE) { + lprintf("error loading image: %s\n", error->message); + g_error_free (error); + gdk_pixbuf_loader_close (this->loader, NULL); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + return; + } + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + GdkPixbuf *pixbuf; + int width, height, x, y, rowstride, n_channels, i; + guchar *img_buf; + yuv_planes_t yuv_planes; + vo_frame_t *img; + + /* + * this->image -> rgb data + */ + if (gdk_pixbuf_loader_close (this->loader, &error) == FALSE) { + lprintf("error loading image: %s\n", error->message); + g_error_free (error); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + return; + } + + pixbuf = gdk_pixbuf_loader_get_pixbuf (this->loader); + if (pixbuf != NULL) + g_object_ref (G_OBJECT (pixbuf)); + g_object_unref (this->loader); + this->loader = NULL; + + if (pixbuf == NULL) { + lprintf("error loading image\n"); + return; + } + + width = gdk_pixbuf_get_width (pixbuf) & ~1; /* must be even for init_yuv_planes */ + height = gdk_pixbuf_get_height (pixbuf); + img_buf = gdk_pixbuf_get_pixels (pixbuf); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); + + lprintf("image loaded successfully\n"); + + /* + * rgb data -> yuv_planes + */ + init_yuv_planes(&yuv_planes, width, height); + + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + i = 0; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + guchar *p; + p = img_buf + y * rowstride + x * n_channels; + + yuv_planes.y[i] = COMPUTE_Y (p[0], p[1], p[2]); + yuv_planes.u[i] = COMPUTE_U (p[0], p[1], p[2]); + yuv_planes.v[i] = COMPUTE_V (p[0], p[1], p[2]); + + i++; + } + } + gdk_pixbuf_unref (pixbuf); + + /* + * alloc and draw video frame + */ + img = this->stream->video_out->get_frame (this->stream->video_out, width, + height, (double)width/(double)height, + XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + img->pts = buf->pts; + img->duration = 3600; + img->bad_frame = 0; + + yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); + free_yuv_planes(&yuv_planes); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); + + img->draw(img, this->stream); + img->free(img); + } +} + + +static void image_flush (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * flush out any frames that are still stored in the decoder + */ +} + + +static void image_reset (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + /* + * reset decoder after engine flush (prepare for new + * video data not related to recently decoded data) + */ + + if (this->loader != NULL) { + gdk_pixbuf_loader_close (this->loader, NULL); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + } +} + + +static void image_discontinuity (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * a time reference discontinuity has happened. + * that is, it must forget any currently held pts value + */ +} + +static void image_dispose (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + if (this->video_open) { + lprintf("closing video\n"); + + this->stream->video_out->close(this->stream->video_out, this->stream); + this->video_open = 0; + } + + if (this->loader != NULL) { + gdk_pixbuf_loader_close (this->loader, NULL); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + } + + lprintf("closed\n"); + free (this); +} + + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, + xine_stream_t *stream) { + + image_class_t *cls = (image_class_t *) class_gen; + image_decoder_t *this; + + lprintf("opened\n"); + + g_type_init (); + + this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); + + this->video_decoder.decode_data = image_decode_data; + this->video_decoder.flush = image_flush; + this->video_decoder.reset = image_reset; + this->video_decoder.discontinuity = image_discontinuity; + this->video_decoder.dispose = image_dispose; + this->cls = cls; + this->stream = stream; + + /* + * initialisation of privates + */ + + return &this->video_decoder; +} + +/* + * image plugin class + */ +static void *init_class (xine_t *xine, void *data) { + + image_class_t *this; + + this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "gdkpixbuf"; + this->decoder_class.description = N_("gdk-pixbuf image video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + /* + * initialisation of privates + */ + + lprintf("class opened\n"); + + return this; +} + +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, BUF_VIDEO_JPEG, 0 }; + +static const decoder_info_t dec_info_image = { + supported_types, /* supported types */ + 7 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "gdkpixbuf", XINE_VERSION_CODE, &dec_info_image, init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/image.c b/src/video_dec/image.c new file mode 100644 index 000000000..e84312624 --- /dev/null +++ b/src/video_dec/image.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2003-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * a image video decoder + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "image_video_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#ifdef PACKAGE_NAME +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#endif + +#include +#include +#include +#include +#include "bswap.h" + +typedef struct { + video_decoder_class_t decoder_class; + + /* + * private variables + */ + +} image_class_t; + + +typedef struct image_decoder_s { + video_decoder_t video_decoder; + + image_class_t *cls; + + xine_stream_t *stream; + int video_open; + + unsigned char *image; + int index; + +} image_decoder_t; + + +static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + if (!this->video_open) { + lprintf("opening video\n"); + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->video_open = 1; + } + + xine_buffer_copyin(this->image, this->index, buf->mem, buf->size); + this->index += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + int width, height, i; + MagickBooleanType status; + MagickWand *wand; + uint8_t *img_buf, *img_buf_ptr; + yuv_planes_t yuv_planes; + vo_frame_t *img; + + /* + * this->image -> rgb data + */ + wand = NewMagickWand(); + status = MagickReadImageBlob(wand, this->image, this->index); + this->index = 0; + + if (status == MagickFalse) { + DestroyMagickWand(wand); + lprintf("error loading image\n"); + return; + } + + width = MagickGetImageWidth(wand) & ~1; /* must be even for init_yuv_planes */ + height = MagickGetImageHeight(wand); + img_buf = malloc(width * height * 3); + MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); + DestroyMagickWand(wand); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); + + lprintf("image loaded successfully\n"); + + /* + * rgb data -> yuv_planes + */ + init_yuv_planes(&yuv_planes, width, height); + + img_buf_ptr = img_buf; + for (i=0; i < width*height; i++) { + uint8_t r = *(img_buf_ptr++); + uint8_t g = *(img_buf_ptr++); + uint8_t b = *(img_buf_ptr++); + + yuv_planes.y[i] = COMPUTE_Y(r, g, b); + yuv_planes.u[i] = COMPUTE_U(r, g, b); + yuv_planes.v[i] = COMPUTE_V(r, g, b); + } + free(img_buf); + + /* + * alloc and draw video frame + */ + img = this->stream->video_out->get_frame (this->stream->video_out, width, + height, (double)width/(double)height, + XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + img->pts = buf->pts; + img->duration = 3600; + img->bad_frame = 0; + + yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); + free_yuv_planes(&yuv_planes); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); + + img->draw(img, this->stream); + img->free(img); + } +} + + +static void image_flush (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * flush out any frames that are still stored in the decoder + */ +} + + +static void image_reset (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + /* + * reset decoder after engine flush (prepare for new + * video data not related to recently decoded data) + */ + + this->index = 0; +} + + +static void image_discontinuity (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * a time reference discontinuity has happened. + * that is, it must forget any currently held pts value + */ +} + +static void image_dispose (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + if (this->video_open) { + lprintf("closing video\n"); + + this->stream->video_out->close(this->stream->video_out, this->stream); + this->video_open = 0; + } + + xine_buffer_free(this->image); + + lprintf("closed\n"); + free (this); +} + + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, + xine_stream_t *stream) { + + image_class_t *cls = (image_class_t *) class_gen; + image_decoder_t *this; + + lprintf("opened\n"); + + this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); + + this->video_decoder.decode_data = image_decode_data; + this->video_decoder.flush = image_flush; + this->video_decoder.reset = image_reset; + this->video_decoder.discontinuity = image_discontinuity; + this->video_decoder.dispose = image_dispose; + this->cls = cls; + this->stream = stream; + + /* + * initialisation of privates + */ + + this->image = xine_buffer_init(10240); + + return &this->video_decoder; +} + +/* + * image plugin class + */ +static void *init_class (xine_t *xine, void *data) { + + image_class_t *this; + + this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "imagevdec"; + this->decoder_class.description = N_("image video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + /* + * initialisation of privates + */ + + lprintf("class opened\n"); + + return this; +} + +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, + 0 }; + +static const decoder_info_t dec_info_image = { + supported_types, /* supported types */ + 6 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "image", XINE_VERSION_CODE, &dec_info_image, init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/rgb.c b/src/video_dec/rgb.c new file mode 100644 index 000000000..9c8409e5f --- /dev/null +++ b/src/video_dec/rgb.c @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Raw RGB "Decoder" by Mike Melanson (melanson@pcisys.net) + * Actually, this decoder just converts a raw RGB image to a YUY2 map + * suitable for display under xine. + * + * This decoder deals with raw RGB data from Microsoft and Quicktime files. + * Data from a MS file can be 32-, 24-, 16-, or 8-bit. The latter can also + * be grayscale, depending on whether a palette is present. Data from a QT + * file can be 32-, 24-, 16-, 8-, 4-, 2-, or 1-bit. Any resolutions <= 8 + * can also be greyscale depending on what the QT file specifies. + * + * One more catch: Raw RGB from a Microsoft file is upside down. This is + * indicated by a negative height parameter. + */ + +#include +#include +#include +#include +#include + +#define LOG_MODULE "rgb" +#define LOG_VERBOSE +/* +#define LOG +*/ +#include +#include +#include +#include +#include "bswap.h" + +typedef struct { + video_decoder_class_t decoder_class; +} rgb_class_t; + +typedef struct rgb_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + rgb_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + double ratio; /* the width to height ratio */ + int bytes_per_pixel; + int bit_depth; + int upside_down; + + unsigned char yuv_palette[256 * 4]; + yuv_planes_t yuv_planes; + +} rgb_decoder_t; + +static void rgb_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + rgb_decoder_t *this = (rgb_decoder_t *) this_gen; + xine_bmiheader *bih; + palette_entry_t *palette; + int i; + int pixel_ptr, row_ptr; + int palette_index; + int buf_ptr; + unsigned int packed_pixel; + unsigned char r, g, b; + int pixels_left; + unsigned char pixel_byte = 0; + + vo_frame_t *img; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && + (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { + palette = (palette_entry_t *)buf->decoder_info_ptr[2]; + for (i = 0; i < buf->decoder_info[2]; i++) { + this->yuv_palette[i * 4 + 0] = + COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 1] = + COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 2] = + COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); + } + } + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + bih = (xine_bmiheader *) buf->content; + this->width = (bih->biWidth + 3) & ~0x03; + this->height = (bih->biHeight + 3) & ~0x03; + if (this->height < 0) { + this->upside_down = 1; + this->height = -this->height; + } else { + this->upside_down = 0; + } + this->ratio = (double)this->width/(double)this->height; + + this->bit_depth = bih->biBitCount; + if (this->bit_depth > 32) + this->bit_depth &= 0x1F; + /* round this number up in case of 15 */ + lprintf("width = %d, height = %d, bit_depth = %d\n", this->width, this->height, this->bit_depth); + + this->bytes_per_pixel = (this->bit_depth + 1) / 8; + + free (this->buf); + + /* minimal buffer size */ + this->bufsize = this->width * this->height * this->bytes_per_pixel; + this->buf = xine_xmalloc(this->bufsize); + this->size = 0; + + init_yuv_planes(&this->yuv_planes, this->width, this->height); + + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->decoder_ok = 1; + + /* load the stream/meta info */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw RGB"); + + return; + } else if (this->decoder_ok) { + + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + + + /* iterate through each row */ + buf_ptr = 0; + + if (this->upside_down) { + for (row_ptr = this->yuv_planes.row_width * (this->yuv_planes.row_count - 1); + row_ptr >= 0; row_ptr -= this->yuv_planes.row_width) { + for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { + + if (this->bytes_per_pixel == 1) { + + palette_index = this->buf[buf_ptr++]; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + } else if (this->bytes_per_pixel == 2) { + + /* ABGR1555 format, little-endian order */ + packed_pixel = _X_LE_16(&this->buf[buf_ptr]); + buf_ptr += 2; + UNPACK_BGR15(packed_pixel, r, g, b); + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } else { + + /* BGR24 or BGRA32 */ + b = this->buf[buf_ptr++]; + g = this->buf[buf_ptr++]; + r = this->buf[buf_ptr++]; + + /* the next line takes care of 'A' in the 32-bit case */ + buf_ptr += this->bytes_per_pixel - 3; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } + } + } + } else { + + for (row_ptr = 0; row_ptr < this->yuv_planes.row_width * this->yuv_planes.row_count; row_ptr += this->yuv_planes.row_width) { + pixels_left = 0; + for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { + + if (this->bit_depth == 1) { + + if (pixels_left == 0) { + pixels_left = 8; + pixel_byte = *this->buf++; + } + + if (pixel_byte & 0x80) { + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[1 * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[1 * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[1 * 4 + 2]; + } else { + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[0 * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[0 * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[0 * 4 + 2]; + } + pixels_left--; + pixel_byte <<= 1; + + } else if (this->bit_depth == 2) { + + if (pixels_left == 0) { + pixels_left = 4; + pixel_byte = *this->buf++; + } + + palette_index = (pixel_byte & 0xC0) >> 6; + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + pixels_left--; + pixel_byte <<= 2; + + } else if (this->bit_depth == 4) { + + if (pixels_left == 0) { + pixels_left = 2; + pixel_byte = *this->buf++; + } + + palette_index = (pixel_byte & 0xF0) >> 4; + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + pixels_left--; + pixel_byte <<= 4; + + } else if (this->bytes_per_pixel == 1) { + + palette_index = this->buf[buf_ptr++]; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + } else if (this->bytes_per_pixel == 2) { + + /* ARGB1555 format, big-endian order */ + packed_pixel = _X_BE_16(&this->buf[buf_ptr]); + buf_ptr += 2; + UNPACK_RGB15(packed_pixel, r, g, b); + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } else { + + /* RGB24 or ARGB32; the next line takes care of 'A' in the + * 32-bit case */ + buf_ptr += this->bytes_per_pixel - 3; + + r = this->buf[buf_ptr++]; + g = this->buf[buf_ptr++]; + b = this->buf[buf_ptr++]; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } + } + } + } + + yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); + + img->draw(img, this->stream); + img->free(img); + + this->size = 0; + } + } +} + +/* + * This function is called when xine needs to flush the system. Not + * sure when or if this is used or even if it needs to do anything. + */ +static void rgb_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void rgb_reset (video_decoder_t *this_gen) { + rgb_decoder_t *this = (rgb_decoder_t *) this_gen; + + this->size = 0; +} + +static void rgb_discontinuity (video_decoder_t *this_gen) { +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void rgb_dispose (video_decoder_t *this_gen) { + rgb_decoder_t *this = (rgb_decoder_t *) this_gen; + + free (this->buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + rgb_decoder_t *this ; + + this = (rgb_decoder_t *) xine_xmalloc (sizeof (rgb_decoder_t)); + + this->video_decoder.decode_data = rgb_decode_data; + this->video_decoder.flush = rgb_flush; + this->video_decoder.reset = rgb_reset; + this->video_decoder.discontinuity = rgb_discontinuity; + this->video_decoder.dispose = rgb_dispose; + this->size = 0; + + this->stream = stream; + this->class = (rgb_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + + return &this->video_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + rgb_class_t *this; + + this = (rgb_class_t *) xine_xmalloc (sizeof (rgb_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "RGB"; + this->decoder_class.description = N_("Raw RGB video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static const uint32_t video_types[] = { + BUF_VIDEO_RGB, + 0 + }; + +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "rgb", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/yuv.c b/src/video_dec/yuv.c new file mode 100644 index 000000000..c1e5825c5 --- /dev/null +++ b/src/video_dec/yuv.c @@ -0,0 +1,373 @@ +/* + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * YUV "Decoder" by Mike Melanson (melanson@pcisys.net) + * Actually, this decoder just reorganizes chunks of raw YUV data in such + * a way that xine can display them. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#define VIDEOBUFSIZE 128*1024 + +typedef struct { + video_decoder_class_t decoder_class; +} yuv_class_t; + +typedef struct yuv_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + yuv_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + double ratio; /* the width to height ratio */ + + int progressive; + int top_field_first; + +} yuv_decoder_t; + +/************************************************************************** + * xine video plugin functions + *************************************************************************/ + +/* + * This function receives a buffer of data from the demuxer layer and + * figures out how to handle it based on its header flags. + */ +static void yuv_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + yuv_decoder_t *this = (yuv_decoder_t *) this_gen; + xine_bmiheader *bih; + + vo_frame_t *img; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + bih = (xine_bmiheader *) buf->content; + this->width = (bih->biWidth + 3) & ~0x03; + this->height = (bih->biHeight + 3) & ~0x03; + + if (buf->decoder_flags & BUF_FLAG_ASPECT) + this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; + else + this->ratio = (double)this->width / (double)this->height; + + this->progressive = buf->decoder_info[3]; + this->top_field_first = buf->decoder_info[4]; + + free (this->buf); + this->buf = NULL; + + this->bufsize = VIDEOBUFSIZE; + this->buf = malloc(this->bufsize); + this->size = 0; + + this->decoder_ok = 1; + + /* load the stream/meta info */ + switch (buf->type) { + + case BUF_VIDEO_YUY2: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YUY2"); + break; + + case BUF_VIDEO_YV12: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YV12"); + break; + + case BUF_VIDEO_YVU9: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YVU9"); + break; + + case BUF_VIDEO_GREY: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Greyscale YUV"); + break; + + case BUF_VIDEO_I420: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw I420"); + break; + + } + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); + + return; + } else if (this->decoder_ok && !(buf->decoder_flags & BUF_FLAG_SPECIAL)) { + uint8_t *src; + + /* if buffer contains an entire frame then there's no need to copy it + * into our internal buffer */ + if ((buf->decoder_flags & BUF_FLAG_FRAME_START) && + (buf->decoder_flags & BUF_FLAG_FRAME_END)) + src = buf->content; + else { + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + src = this->buf; + } + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + if (buf->type == BUF_VIDEO_YUY2) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); + + yuy2_to_yuy2( + /* src */ + src, this->width*2, + /* dst */ + img->base[0], img->pitches[0], + /* width x height */ + this->width, this->height); + + } else if (buf->type == BUF_VIDEO_YV12) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + yv12_to_yv12( + /* Y */ + src, this->width, + img->base[0], img->pitches[0], + /* U */ + src + (this->width * this->height * 5/4), this->width/2, + img->base[1], img->pitches[1], + /* V */ + src + (this->width * this->height), this->width/2, + img->base[2], img->pitches[2], + /* width x height */ + this->width, this->height); + + } else if (buf->type == BUF_VIDEO_I420) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + yv12_to_yv12( + /* Y */ + src, this->width, + img->base[0], img->pitches[0], + /* U */ + src + (this->width * this->height), this->width/2, + img->base[1], img->pitches[1], + /* V */ + src + (this->width * this->height * 5/4), this->width/2, + img->base[2], img->pitches[2], + /* width x height */ + this->width, this->height); + + } else if (buf->type == BUF_VIDEO_YVU9) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + + yuv9_to_yv12( + /* Y */ + src, + this->width, + img->base[0], + img->pitches[0], + /* U */ + src + (this->width * this->height), + this->width / 4, + img->base[1], + img->pitches[1], + /* V */ + src + (this->width * this->height) + + (this->width * this->height / 16), + this->width / 4, + img->base[2], + img->pitches[2], + /* width x height */ + this->width, + this->height); + + } else if (buf->type == BUF_VIDEO_GREY) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + xine_fast_memcpy(img->base[0], src, this->width * this->height); + memset( img->base[1], 0x80, this->width * this->height / 4 ); + memset( img->base[2], 0x80, this->width * this->height / 4 ); + + } else { + + /* just allocate something to avoid compiler warnings */ + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + } + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + + img->draw(img, this->stream); + img->free(img); + + this->size = 0; + } + } +} + +/* + * This function is called when xine needs to flush the system. Not + * sure when or if this is used or even if it needs to do anything. + */ +static void yuv_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void yuv_reset (video_decoder_t *this_gen) { + yuv_decoder_t *this = (yuv_decoder_t *) this_gen; + + this->size = 0; +} + +static void yuv_discontinuity (video_decoder_t *this_gen) { +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void yuv_dispose (video_decoder_t *this_gen) { + yuv_decoder_t *this = (yuv_decoder_t *) this_gen; + + free (this->buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + yuv_decoder_t *this ; + + this = (yuv_decoder_t *) xine_xmalloc (sizeof (yuv_decoder_t)); + + this->video_decoder.decode_data = yuv_decode_data; + this->video_decoder.flush = yuv_flush; + this->video_decoder.reset = yuv_reset; + this->video_decoder.discontinuity = yuv_discontinuity; + this->video_decoder.dispose = yuv_dispose; + this->size = 0; + + this->stream = stream; + this->class = (yuv_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + + return &this->video_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + yuv_class_t *this; + + this = (yuv_class_t *) xine_xmalloc (sizeof (yuv_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "YUV"; + this->decoder_class.description = N_("Raw YUV video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static const uint32_t video_types[] = { + BUF_VIDEO_YUY2, + BUF_VIDEO_YV12, + BUF_VIDEO_YVU9, + BUF_VIDEO_GREY, + BUF_VIDEO_I420, + 0 + }; + +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "yuv", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; -- cgit v1.2.3 From 0ff96f3986d9c31edd14182e22b498a674571f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 23:18:37 +0100 Subject: Move libffmpeg into combined/ffmpeg directory. --HG-- rename : src/libffmpeg/Makefile.am => src/combined/ffmpeg/Makefile.am rename : src/libffmpeg/ff_audio_decoder.c => src/combined/ffmpeg/ff_audio_decoder.c rename : src/libffmpeg/ff_dvaudio_decoder.c => src/combined/ffmpeg/ff_dvaudio_decoder.c rename : src/libffmpeg/ff_mpeg_parser.c => src/combined/ffmpeg/ff_mpeg_parser.c rename : src/libffmpeg/ff_mpeg_parser.h => src/combined/ffmpeg/ff_mpeg_parser.h rename : src/libffmpeg/ff_video_decoder.c => src/combined/ffmpeg/ff_video_decoder.c rename : src/libffmpeg/ffmpeg_decoder.c => src/combined/ffmpeg/ffmpeg_decoder.c rename : src/libffmpeg/ffmpeg_decoder.h => src/combined/ffmpeg/ffmpeg_decoder.h rename : src/libffmpeg/ffmpeg_encoder.c => src/combined/ffmpeg/ffmpeg_encoder.c --- src/Makefile.am | 1 - src/combined/Makefile.am | 2 + src/combined/ffmpeg/Makefile.am | 62 + src/combined/ffmpeg/ff_audio_decoder.c | 541 +++++++++ src/combined/ffmpeg/ff_dvaudio_decoder.c | 412 +++++++ src/combined/ffmpeg/ff_mpeg_parser.c | 321 ++++++ src/combined/ffmpeg/ff_mpeg_parser.h | 81 ++ src/combined/ffmpeg/ff_video_decoder.c | 1816 ++++++++++++++++++++++++++++++ src/combined/ffmpeg/ffmpeg_decoder.c | 55 + src/combined/ffmpeg/ffmpeg_decoder.h | 49 + src/combined/ffmpeg/ffmpeg_encoder.c | 328 ++++++ src/libffmpeg/Makefile.am | 62 - src/libffmpeg/ff_audio_decoder.c | 541 --------- src/libffmpeg/ff_dvaudio_decoder.c | 412 ------- src/libffmpeg/ff_mpeg_parser.c | 321 ------ src/libffmpeg/ff_mpeg_parser.h | 81 -- src/libffmpeg/ff_video_decoder.c | 1816 ------------------------------ src/libffmpeg/ffmpeg_decoder.c | 55 - src/libffmpeg/ffmpeg_decoder.h | 49 - src/libffmpeg/ffmpeg_encoder.c | 328 ------ 20 files changed, 3667 insertions(+), 3666 deletions(-) create mode 100644 src/combined/ffmpeg/Makefile.am create mode 100644 src/combined/ffmpeg/ff_audio_decoder.c create mode 100644 src/combined/ffmpeg/ff_dvaudio_decoder.c create mode 100644 src/combined/ffmpeg/ff_mpeg_parser.c create mode 100644 src/combined/ffmpeg/ff_mpeg_parser.h create mode 100644 src/combined/ffmpeg/ff_video_decoder.c create mode 100644 src/combined/ffmpeg/ffmpeg_decoder.c create mode 100644 src/combined/ffmpeg/ffmpeg_decoder.h create mode 100644 src/combined/ffmpeg/ffmpeg_encoder.c delete mode 100644 src/libffmpeg/Makefile.am delete mode 100644 src/libffmpeg/ff_audio_decoder.c delete mode 100644 src/libffmpeg/ff_dvaudio_decoder.c delete mode 100644 src/libffmpeg/ff_mpeg_parser.c delete mode 100644 src/libffmpeg/ff_mpeg_parser.h delete mode 100644 src/libffmpeg/ff_video_decoder.c delete mode 100644 src/libffmpeg/ffmpeg_decoder.c delete mode 100644 src/libffmpeg/ffmpeg_decoder.h delete mode 100644 src/libffmpeg/ffmpeg_encoder.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 330b099a0..4b16acb35 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,6 @@ SUBDIRS = \ dxr3 \ input \ demuxers \ - libffmpeg \ libmpeg2 \ libspudec \ libspucc \ diff --git a/src/combined/Makefile.am b/src/combined/Makefile.am index 0784b8044..92d49a3e5 100644 --- a/src/combined/Makefile.am +++ b/src/combined/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = ffmpeg + include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) diff --git a/src/combined/ffmpeg/Makefile.am b/src/combined/ffmpeg/Makefile.am new file mode 100644 index 000000000..42fe20f95 --- /dev/null +++ b/src/combined/ffmpeg/Makefile.am @@ -0,0 +1,62 @@ +include $(top_srcdir)/misc/Makefile.common + +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) +AM_CPPFLAGS = $(ZLIB_CPPFLAGS) +AM_LDFLAGS = $(xineplug_ldflags) + +if WITH_EXTERNAL_FFMPEG +AM_CFLAGS += $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS) +link_ffmpeg = $(FFMPEG_LIBS) $(FFMPEG_POSTPROC_LIBS) +else +AM_CPPFLAGS += -I$(top_srcdir)/contrib/ffmpeg/libavutil \ + -I$(top_srcdir)/contrib/ffmpeg/libavcodec \ + -I$(top_srcdir)/contrib/ffmpeg/libpostproc +link_ffmpeg = $(top_builddir)/contrib/ffmpeg/libavcodec/libavcodec.a \ + $(top_builddir)/contrib/ffmpeg/libavutil/libavutil.a \ + $(top_builddir)/contrib/ffmpeg/libpostproc/libpostproc.a + +$(top_builddir)/contrib/ffmpeg/libavcodec/libavcodec.a: + $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/libavcodec/libavcodec.a + +$(top_builddir)/contrib/ffmpeg/libavutil/libavutil.a: + $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/libavutil/libavutil.a + +$(top_builddir)/contrib/ffmpeg/libpostproc/libpostproc.a: + $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/libpostproc/libpostproc.a + +$(top_builddir)/contrib/ffmpeg/config.h: + $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/config.mak + +ffmpeg_config.h: $(top_builddir)/contrib/ffmpeg/config.h + cp $(top_builddir)/contrib/ffmpeg/config.h ffmpeg_config.h + +BUILT_SOURCES = ffmpeg_config.h +CLEANFILES = $(BUILT_SOURCES) + +endif + +# this must always be included, even if the current machine has no DXR3... +EXTRA_DIST = ffmpeg_encoder.c + +xineplug_LTLIBRARIES = xineplug_decode_ff.la xineplug_decode_dvaudio.la + +if ENABLE_DXR3 +AM_CFLAGS += $(X_CFLAGS) +AM_CPPFLAGS += -I$(top_srcdir)/src/dxr3 +xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \ + ffmpeg_encoder.c ff_mpeg_parser.c ffmpeg_decoder.h \ + ff_mpeg_parser.h +else +xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \ + ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h +endif + +nodist_xineplug_decode_ff_la_SOURCES = ffmpeg_config.h + +xineplug_decode_ff_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) -lm $(ZLIB_LIBS) \ + $(link_ffmpeg) $(PTHREAD_LIBS) $(LTLIBINTL) +xineplug_decode_ff_la_LDFLAGS = $(AM_LDFLAGS) $(IMPURE_TEXT_LDFLAGS) + +xineplug_decode_dvaudio_la_SOURCES = ff_dvaudio_decoder.c +xineplug_decode_dvaudio_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) +xineplug_decode_dvaudio_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/contrib/ffmpeg/libavcodec diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c new file mode 100644 index 000000000..dd03cd2a3 --- /dev/null +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -0,0 +1,541 @@ +/* + * Copyright (C) 2001-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * xine audio decoder plugin using ffmpeg + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +# ifndef HAVE_FFMPEG +# include "ffmpeg_config.h" +# endif +#endif + +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "ffmpeg_audio_dec" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include "bswap.h" +#include "ffmpeg_decoder.h" + +#define AUDIOBUFSIZE (64 * 1024) + +typedef struct { + audio_decoder_class_t decoder_class; +} ff_audio_class_t; + +typedef struct ff_audio_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + int output_open; + int audio_channels; + int audio_bits; + int audio_sample_rate; + + unsigned char *buf; + int bufsize; + int size; + + AVCodecContext *context; + AVCodec *codec; + + char *decode_buffer; + int decoder_ok; + +} ff_audio_decoder_t; + + +static const ff_codec_t ff_audio_lookup[] = { + {BUF_AUDIO_WMAV1, CODEC_ID_WMAV1, "MS Windows Media Audio 1 (ffmpeg)"}, + {BUF_AUDIO_WMAV2, CODEC_ID_WMAV2, "MS Windows Media Audio 2 (ffmpeg)"}, + {BUF_AUDIO_14_4, CODEC_ID_RA_144, "Real 14.4 (ffmpeg)"}, + {BUF_AUDIO_28_8, CODEC_ID_RA_288, "Real 28.8 (ffmpeg)"}, + {BUF_AUDIO_MPEG, CODEC_ID_MP3, "MP3 (ffmpeg)"}, + {BUF_AUDIO_MSADPCM, CODEC_ID_ADPCM_MS, "MS ADPCM (ffmpeg)"}, + {BUF_AUDIO_QTIMAADPCM, CODEC_ID_ADPCM_IMA_QT, "QT IMA ADPCM (ffmpeg)"}, + {BUF_AUDIO_MSIMAADPCM, CODEC_ID_ADPCM_IMA_WAV, "MS IMA ADPCM (ffmpeg)"}, + {BUF_AUDIO_DK3ADPCM, CODEC_ID_ADPCM_IMA_DK3, "Duck DK3 ADPCM (ffmpeg)"}, + {BUF_AUDIO_DK4ADPCM, CODEC_ID_ADPCM_IMA_DK4, "Duck DK4 ADPCM (ffmpeg)"}, + {BUF_AUDIO_VQA_IMA, CODEC_ID_ADPCM_IMA_WS, "Westwood Studios IMA (ffmpeg)"}, + {BUF_AUDIO_SMJPEG_IMA, CODEC_ID_ADPCM_IMA_SMJPEG, "SMJPEG IMA (ffmpeg)"}, + {BUF_AUDIO_XA_ADPCM, CODEC_ID_ADPCM_XA, "CD-ROM/XA ADPCM (ffmpeg)"}, + {BUF_AUDIO_4X_ADPCM, CODEC_ID_ADPCM_4XM, "4X ADPCM (ffmpeg)"}, + {BUF_AUDIO_EA_ADPCM, CODEC_ID_ADPCM_EA, "Electronic Arts ADPCM (ffmpeg)"}, + {BUF_AUDIO_MULAW, CODEC_ID_PCM_MULAW, "mu-law logarithmic PCM (ffmpeg)"}, + {BUF_AUDIO_ALAW, CODEC_ID_PCM_ALAW, "A-law logarithmic PCM (ffmpeg)"}, + {BUF_AUDIO_ROQ, CODEC_ID_ROQ_DPCM, "RoQ DPCM (ffmpeg)"}, + {BUF_AUDIO_INTERPLAY, CODEC_ID_INTERPLAY_DPCM, "Interplay DPCM (ffmpeg)"}, + {BUF_AUDIO_MAC3, CODEC_ID_MACE3, "MACE 3:1 (ffmpeg)"}, + {BUF_AUDIO_MAC6, CODEC_ID_MACE6, "MACE 6:1 (ffmpeg)"}, + {BUF_AUDIO_XAN_DPCM, CODEC_ID_XAN_DPCM, "Origin Xan DPCM (ffmpeg)"}, + {BUF_AUDIO_VMD, CODEC_ID_VMDAUDIO, "Sierra VMD Audio (ffmpeg)"}, + {BUF_AUDIO_FLAC, CODEC_ID_FLAC, "FLAC (ffmpeg)"}, + {BUF_AUDIO_SHORTEN, CODEC_ID_SHORTEN, "Shorten (ffmpeg)"}, + {BUF_AUDIO_ALAC, CODEC_ID_ALAC, "ALAC (ffmpeg)"}, + {BUF_AUDIO_QDESIGN2, CODEC_ID_QDM2, "QDesign (ffmpeg)"}, + {BUF_AUDIO_COOK, CODEC_ID_COOK, "RealAudio Cooker (ffmpeg)"}, + {BUF_AUDIO_TRUESPEECH, CODEC_ID_TRUESPEECH, "TrueSpeech (ffmpeg)"}, + {BUF_AUDIO_TTA, CODEC_ID_TTA, "True Audio Lossless (ffmpeg)"}, + {BUF_AUDIO_SMACKER, CODEC_ID_SMACKAUDIO, "Smacker (ffmpeg)"}, + {BUF_AUDIO_FLVADPCM, CODEC_ID_ADPCM_SWF, "Flash ADPCM (ffmpeg)"}, + {BUF_AUDIO_WAVPACK, CODEC_ID_WAVPACK, "WavPack (ffmpeg)"}, +}; + + + static void ff_audio_ensure_buffer_size(ff_audio_decoder_t *this, int size) { + if (size > this->bufsize) { + this->bufsize = size + size / 2; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), + this->bufsize); + this->buf = realloc( this->buf, this->bufsize ); + } +} + +static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen; + int bytes_consumed; + int decode_buffer_size; + int offset; + int out; + audio_buffer_t *audio_buffer; + int bytes_to_send; + + if ( (buf->decoder_flags & BUF_FLAG_HEADER) && + !(buf->decoder_flags & BUF_FLAG_SPECIAL) ) { + + /* accumulate init data */ + ff_audio_ensure_buffer_size(this, this->size + buf->size); + memcpy(this->buf + this->size, buf->content, buf->size); + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + size_t i; + unsigned int codec_type; + xine_waveformatex *audio_header; + + codec_type = buf->type & 0xFFFF0000; + this->codec = NULL; + + for(i = 0; i < sizeof(ff_audio_lookup)/sizeof(ff_codec_t); i++) + if(ff_audio_lookup[i].type == codec_type) { + pthread_mutex_lock (&ffmpeg_lock); + this->codec = avcodec_find_decoder(ff_audio_lookup[i].id); + pthread_mutex_unlock (&ffmpeg_lock); + _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, + ff_audio_lookup[i].name); + break; + } + + if (!this->codec) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"), + codec_type); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + return; + } + + this->context = avcodec_alloc_context(); + + if(buf->decoder_flags & BUF_FLAG_STDHEADER) { + this->audio_sample_rate = buf->decoder_info[1]; + this->audio_channels = buf->decoder_info[3]; + + if(this->size) { + audio_header = (xine_waveformatex *)this->buf; + + this->context->block_align = audio_header->nBlockAlign; + this->context->bit_rate = audio_header->nAvgBytesPerSec * 8; + + if(audio_header->cbSize > 0) { + this->context->extradata = xine_xmalloc(audio_header->cbSize); + this->context->extradata_size = audio_header->cbSize; + memcpy( this->context->extradata, + (uint8_t *)audio_header + sizeof(xine_waveformatex), + audio_header->cbSize ); + } + } + } else { + short *ptr; + + switch(codec_type) { + case BUF_AUDIO_14_4: + this->audio_sample_rate = 8000; + this->audio_channels = 1; + + this->context->block_align = 240; + break; + case BUF_AUDIO_28_8: + this->audio_sample_rate = _X_BE_16(&this->buf[0x30]); + this->audio_channels = this->buf[0x37]; + /* this->audio_bits = buf->content[0x35] */ + + this->context->block_align = _X_BE_16(&this->buf[0x2A]); + + this->context->extradata_size = 5*sizeof(short); + this->context->extradata = xine_xmalloc(this->context->extradata_size); + + ptr = (short *) this->context->extradata; + + ptr[0] = _X_BE_16(&this->buf[0x2C]); /* subpacket size */ + ptr[1] = _X_BE_16(&this->buf[0x28]); /* subpacket height */ + ptr[2] = _X_BE_16(&this->buf[0x16]); /* subpacket flavour */ + ptr[3] = _X_BE_32(&this->buf[0x18]); /* coded frame size */ + ptr[4] = 0; /* codec's data length */ + break; + default: + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type); + break; + } + } + + /* Current ffmpeg audio decoders always use 16 bits/sample + * buf->decoder_info[2] can't be used as it doesn't refer to the output + * bits/sample for some codecs (e.g. MS ADPCM) */ + this->audio_bits = 16; + + this->context->bits_per_sample = this->audio_bits; + this->context->sample_rate = this->audio_sample_rate; + this->context->channels = this->audio_channels; + this->context->codec_id = this->codec->id; + this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC); + + this->size = 0; + + this->decode_buffer = xine_xmalloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); + + return; + } + } else if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && + (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM)) { + + this->context->extradata_size = buf->decoder_info[2]; + this->context->extradata = xine_xmalloc(buf->decoder_info[2] + + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(this->context->extradata, buf->decoder_info_ptr[2], + buf->decoder_info[2]); + + } else if (!(buf->decoder_flags & BUF_FLAG_SPECIAL)) { + + if( !this->decoder_ok ) { + if ( ! this->context || ! this->codec ) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: trying to open null codec\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + return; + } + + pthread_mutex_lock (&ffmpeg_lock); + if (avcodec_open (this->context, this->codec) < 0) { + pthread_mutex_unlock (&ffmpeg_lock); + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: couldn't open decoder\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + return; + } + pthread_mutex_unlock (&ffmpeg_lock); + this->decoder_ok = 1; + } + + if (!this->output_open) { + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, this->audio_bits, this->audio_sample_rate, + _x_ao_channels2mode(this->audio_channels)); + } + + /* if the audio still isn't open, bail */ + if (!this->output_open) + return; + + if( buf->decoder_flags & BUF_FLAG_PREVIEW ) + return; + + ff_audio_ensure_buffer_size(this, this->size + buf->size); + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ + + offset = 0; + while (this->size>0) { + decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; + bytes_consumed = avcodec_decode_audio2 (this->context, + (int16_t *)this->decode_buffer, + &decode_buffer_size, + &this->buf[offset], + this->size); + + if (bytes_consumed<0) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_audio_dec: error decompressing audio frame\n"); + this->size=0; + return; + } else if (bytes_consumed == 0 && decode_buffer_size == 0) { + if (offset) + memmove(this->buf, &this->buf[offset], this->size); + return; + } + + /* dispatch the decoded audio */ + out = 0; + while (out < decode_buffer_size) { + audio_buffer = + this->stream->audio_out->get_buffer (this->stream->audio_out); + if (audio_buffer->mem_size == 0) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_audio_dec: Help! Allocated audio buffer with nothing in it!\n"); + return; + } + + if ((decode_buffer_size - out) > audio_buffer->mem_size) + bytes_to_send = audio_buffer->mem_size; + else + bytes_to_send = decode_buffer_size - out; + + /* fill up this buffer */ + xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out], + bytes_to_send); + /* byte count / 2 (bytes / sample) / channels */ + audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels; + + audio_buffer->vpts = buf->pts; + buf->pts = 0; /* only first buffer gets the real pts */ + this->stream->audio_out->put_buffer (this->stream->audio_out, + audio_buffer, this->stream); + + out += bytes_to_send; + } + + this->size -= bytes_consumed; + offset += bytes_consumed; + } + + /* reset internal accumulation buffer */ + this->size = 0; + } + } +} + +static void ff_audio_reset (audio_decoder_t *this_gen) { + ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen; + + this->size = 0; + + /* try to reset the wma decoder */ + if( this->context && this->decoder_ok ) { + pthread_mutex_lock (&ffmpeg_lock); + avcodec_close (this->context); + avcodec_open (this->context, this->codec); + pthread_mutex_unlock (&ffmpeg_lock); + } +} + +static void ff_audio_discontinuity (audio_decoder_t *this_gen) { +} + +static void ff_audio_dispose (audio_decoder_t *this_gen) { + + ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen; + + if( this->context && this->decoder_ok ) { + pthread_mutex_lock (&ffmpeg_lock); + avcodec_close (this->context); + pthread_mutex_unlock (&ffmpeg_lock); + } + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + + free(this->buf); + free(this->decode_buffer); + + if(this->context && this->context->extradata) + free(this->context->extradata); + + if(this->context) + free(this->context); + + free (this_gen); +} + +static audio_decoder_t *ff_audio_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + ff_audio_decoder_t *this ; + + this = (ff_audio_decoder_t *) xine_xmalloc (sizeof (ff_audio_decoder_t)); + + this->audio_decoder.decode_data = ff_audio_decode_data; + this->audio_decoder.reset = ff_audio_reset; + this->audio_decoder.discontinuity = ff_audio_discontinuity; + this->audio_decoder.dispose = ff_audio_dispose; + + this->output_open = 0; + this->audio_channels = 0; + this->stream = stream; + this->buf = NULL; + this->size = 0; + this->bufsize = 0; + this->decoder_ok = 0; + + ff_audio_ensure_buffer_size(this, AUDIOBUFSIZE); + + return &this->audio_decoder; +} + +void *init_audio_plugin (xine_t *xine, void *data) { + + ff_audio_class_t *this ; + + this = (ff_audio_class_t *) xine_xmalloc (sizeof (ff_audio_class_t)); + + this->decoder_class.open_plugin = ff_audio_open_plugin; + this->decoder_class.identifier = "ffmpeg audio"; + this->decoder_class.description = N_("ffmpeg based audio decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + pthread_once( &once_control, init_once_routine ); + + return this; +} + +static uint32_t supported_audio_types[] = { +#if defined(HAVE_FFMPEG) || CONFIG_WMAV1_DECODER + BUF_AUDIO_WMAV1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WMAV2_DECODER + BUF_AUDIO_WMAV2, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_RA_144_DECODER + BUF_AUDIO_14_4, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_RA_288_DECODER + BUF_AUDIO_28_8, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MP3_DECODER + BUF_AUDIO_MPEG, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_MS_DECODER + BUF_AUDIO_MSADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_QT_DECODER + BUF_AUDIO_QTIMAADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_WAV_DECODER + BUF_AUDIO_MSIMAADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_DK3_DECODER + BUF_AUDIO_DK3ADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_DK4_DECODER + BUF_AUDIO_DK4ADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_WS_DECODER + BUF_AUDIO_VQA_IMA, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_SMJPEG_DECODER + BUF_AUDIO_SMJPEG_IMA, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_XA_DECODER + BUF_AUDIO_XA_ADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_4XM_DECODER + BUF_AUDIO_4X_ADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_EA_DECODER + BUF_AUDIO_EA_ADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_PCM_MULAW_DECODER + BUF_AUDIO_MULAW, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_PCM_ALAW_DECODER + BUF_AUDIO_ALAW, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ROQ_DPCM_DECODER + BUF_AUDIO_ROQ, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_INTERPLAY_DPCM_DECODER + BUF_AUDIO_INTERPLAY, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MACE3_DECODER + BUF_AUDIO_MAC3, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MACE6_DECODER + BUF_AUDIO_MAC6, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_XAN_DPCM_DECODER + BUF_AUDIO_XAN_DPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VMDAUDIO_DECODER + BUF_AUDIO_VMD, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_FLAC_DECODER + BUF_AUDIO_FLAC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_SHORTEN_DECODER + BUF_AUDIO_SHORTEN, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ALAC_DECODER + BUF_AUDIO_ALAC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_QDM2_DECODER + BUF_AUDIO_QDESIGN2, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_COOK_DECODER + BUF_AUDIO_COOK, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_TRUESPEECH_DECODER + BUF_AUDIO_TRUESPEECH, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_TTA_DECODER + BUF_AUDIO_TTA, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_SMACKAUDIO_DECODER + BUF_AUDIO_SMACKER, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_SWF_DECODER + BUF_AUDIO_FLVADPCM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WAVPACK_DECODER + BUF_AUDIO_WAVPACK, +#endif + + 0 +}; + +decoder_info_t dec_info_ffmpeg_audio = { + supported_audio_types, /* supported types */ + 6 /* priority */ +}; diff --git a/src/combined/ffmpeg/ff_dvaudio_decoder.c b/src/combined/ffmpeg/ff_dvaudio_decoder.c new file mode 100644 index 000000000..aced7f5bb --- /dev/null +++ b/src/combined/ffmpeg/ff_dvaudio_decoder.c @@ -0,0 +1,412 @@ +/* + * Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * dv audio decoder based on patch by Dan Dennedy + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#define LOG_MODULE "dvaudio" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include + +#ifdef _MSC_VER +/* ffmpeg has own definitions of those types */ +# undef int8_t +# undef uint8_t +# undef int16_t +# undef uint16_t +# undef int32_t +# undef uint32_t +# undef int64_t +# undef uint64_t +#endif + +#include +#include /* This is not installed by FFmpeg, its usage has to be cleared up */ + +#ifdef _MSC_VER +# undef malloc +# undef free +# undef realloc +#endif + +#define AUDIOBUFSIZE 128*1024 +#define MAXFRAMESIZE 131072 + + +typedef struct { + audio_decoder_class_t decoder_class; +} dvaudio_class_t; + +typedef struct dvaudio_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + int output_open; + int audio_channels; + int audio_bits; + int audio_sample_rate; + + unsigned char *buf; + int bufsize; + int size; + + char *decode_buffer; + int decoder_ok; + +} dvaudio_decoder_t; + +/* + * This is the dumbest implementation of all -- it simply looks at + * a fixed offset and if pack isn't there -- fails. We might want + * to have a fallback mechanism for complete search of missing packs. + */ +static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) +{ + int offs; + + switch (t) { + case dv_audio_source: + offs = (80*6 + 80*16*3 + 3); + break; + case dv_audio_control: + offs = (80*6 + 80*16*4 + 3); + break; + case dv_video_control: + offs = (80*5 + 48 + 5); + break; + default: + return NULL; + } + + return (frame[offs] == t ? &frame[offs] : NULL); +} + +static inline uint16_t dv_audio_12to16(uint16_t sample) +{ + uint16_t shift, result; + + sample = (sample < 0x800) ? sample : sample | 0xf000; + shift = (sample & 0xf00) >> 8; + + if (shift < 0x2 || shift > 0xd) { + result = sample; + } else if (shift < 0x8) { + shift--; + result = (sample - (256 * shift)) << shift; + } else { + shift = 0xe - shift; + result = ((sample + ((256 * shift) + 1)) << shift) - 1; + } + + return result; +} + +/* + * There's a couple of assumptions being made here: + * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. + * We can pass them upwards when ffmpeg will be ready to deal with them. + * 2. We don't do software emphasis. + * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples + * are converted into 16bit linear ones. + */ +static int dv_extract_audio(uint8_t* frame, uint8_t* pcm, uint8_t* pcm2) +{ + int size, i, j, d, of, smpls, freq, quant, half_ch; + uint16_t lc, rc; + const DVprofile* sys; + const uint8_t* as_pack; + + as_pack = dv_extract_pack(frame, dv_audio_source); + if (!as_pack) /* No audio ? */ + return 0; + + sys = dv_frame_profile(frame); + smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ + freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */ + quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ + + if (quant > 1) + return -1; /* Unsupported quantization */ + + size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ + half_ch = sys->difseg_size/2; + + /* for each DIF segment */ + for (i = 0; i < sys->difseg_size; i++) { + frame += 6 * 80; /* skip DIF segment header */ + if (quant == 1 && i == half_ch) { + if (!pcm2) + break; + else + pcm = pcm2; + } + + for (j = 0; j < 9; j++) { + for (d = 8; d < 80; d += 2) { + if (quant == 0) { /* 16bit quantization */ + of = sys->audio_shuffle[i][j] + (d - 8)/2 * sys->audio_stride; + if (of*2 >= size) + continue; + +#ifdef WORDS_BIGENDIAN + pcm[of*2] = frame[d]; + pcm[of*2+1] = frame[d+1]; +#else + pcm[of*2] = frame[d+1]; + pcm[of*2+1] = frame[d]; +#endif + if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00) + pcm[of*2+1] = 0; + } else { /* 12bit quantization */ + lc = ((uint16_t)frame[d] << 4) | + ((uint16_t)frame[d+2] >> 4); + rc = ((uint16_t)frame[d+1] << 4) | + ((uint16_t)frame[d+2] & 0x0f); + lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc)); + rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc)); + + of = sys->audio_shuffle[i%half_ch][j] + (d - 8)/3 * sys->audio_stride; + if (of*2 >= size) + continue; + +#ifdef WORDS_BIGENDIAN + pcm[of*2] = lc >> 8; + pcm[of*2+1] = lc & 0xff; +#else + pcm[of*2] = lc & 0xff; + pcm[of*2+1] = lc >> 8; +#endif + of = sys->audio_shuffle[i%half_ch+half_ch][j] + + (d - 8)/3 * sys->audio_stride; +#ifdef WORDS_BIGENDIAN + pcm[of*2] = rc >> 8; + pcm[of*2+1] = rc & 0xff; +#else + pcm[of*2] = rc & 0xff; + pcm[of*2+1] = rc >> 8; +#endif + ++d; + } + } + + frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ + } + } + + return size; +} + +static void dvaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { + + dvaudio_decoder_t *this = (dvaudio_decoder_t *) this_gen; + int bytes_consumed; + int decode_buffer_size; + int offset; + int out; + audio_buffer_t *audio_buffer; + int bytes_to_send; + + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { + this->buf = xine_xmalloc(AUDIOBUFSIZE); + this->bufsize = AUDIOBUFSIZE; + this->size = 0; + this->decode_buffer = xine_xmalloc(MAXFRAMESIZE); + + this->audio_sample_rate = buf->decoder_info[1]; + this->audio_bits = buf->decoder_info[2]; + this->audio_channels = buf->decoder_info[3]; + + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DV Audio"); + + this->decoder_ok = 1; + + return; + } + + if (this->decoder_ok && !(buf->decoder_flags & (BUF_FLAG_HEADER|BUF_FLAG_SPECIAL))) { + + if (!this->output_open) { + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, this->audio_bits, this->audio_sample_rate, + _x_ao_channels2mode(this->audio_channels)); + } + + /* if the audio still isn't open, bail */ + if (!this->output_open) + return; + + if( this->size + buf->size > this->bufsize ) { + this->bufsize = this->size + 2 * buf->size; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("dvaudio: increasing buffer to %d to avoid overflow.\n"), + this->bufsize); + this->buf = realloc( this->buf, this->bufsize ); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ + + offset = 0; + while (this->size>0) { + decode_buffer_size = dv_extract_audio(&this->buf[offset], this->decode_buffer, NULL); + + if (decode_buffer_size > -1) + bytes_consumed = dv_frame_profile(&this->buf[offset])->frame_size; + else + bytes_consumed = decode_buffer_size; + + /* dispatch the decoded audio */ + out = 0; + while (out < decode_buffer_size) { + audio_buffer = + this->stream->audio_out->get_buffer (this->stream->audio_out); + if (audio_buffer->mem_size == 0) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "dvaudio: Help! Allocated audio buffer with nothing in it!\n"); + return; + } + + if ((decode_buffer_size - out) > audio_buffer->mem_size) + bytes_to_send = audio_buffer->mem_size; + else + bytes_to_send = decode_buffer_size - out; + + /* fill up this buffer */ + xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out], + bytes_to_send); + /* byte count / 2 (bytes / sample) / channels */ + audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels; + + audio_buffer->vpts = buf->pts; + buf->pts = 0; /* only first buffer gets the real pts */ + this->stream->audio_out->put_buffer (this->stream->audio_out, + audio_buffer, this->stream); + + out += bytes_to_send; + } + + this->size -= bytes_consumed; + offset += bytes_consumed; + } + + /* reset internal accumulation buffer */ + this->size = 0; + } + } +} + +static void dvaudio_reset (audio_decoder_t *this_gen) { + dvaudio_decoder_t *this = (dvaudio_decoder_t *) this_gen; + + this->size = 0; +} + +static void dvaudio_discontinuity (audio_decoder_t *this_gen) { +} + +static void dvaudio_dispose (audio_decoder_t *this_gen) { + + dvaudio_decoder_t *this = (dvaudio_decoder_t *) this_gen; + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + + free(this->buf); + free(this->decode_buffer); + + free (this_gen); +} + +static audio_decoder_t *dvaudio_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + dvaudio_decoder_t *this ; + + this = (dvaudio_decoder_t *) xine_xmalloc (sizeof (dvaudio_decoder_t)); + + this->audio_decoder.decode_data = dvaudio_decode_data; + this->audio_decoder.reset = dvaudio_reset; + this->audio_decoder.discontinuity = dvaudio_discontinuity; + this->audio_decoder.dispose = dvaudio_dispose; + + this->output_open = 0; + this->audio_channels = 0; + this->stream = stream; + this->buf = NULL; + this->size = 0; + this->decoder_ok = 0; + + return &this->audio_decoder; +} + +static void *init_dvaudio_plugin (xine_t *xine, void *data) { + + dvaudio_class_t *this ; + + this = (dvaudio_class_t *) xine_xmalloc (sizeof (dvaudio_class_t)); + + this->decoder_class.open_plugin = dvaudio_open_plugin; + this->decoder_class.identifier = "dv audio"; + this->decoder_class.description = N_("dv audio decoder plugin"); + this->decoder_class.dispose = default_audio_decoder_class_dispose; + + return this; +} + +static uint32_t supported_audio_types[] = { + BUF_AUDIO_DV, + 0 +}; + +static const decoder_info_t dec_info_dvaudio = { + supported_audio_types, /* supported types */ + 5 /* priority */ +}; + +/* + * exported plugin catalog entry + */ + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 16, "dvaudio", XINE_VERSION_CODE, &dec_info_dvaudio, init_dvaudio_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/combined/ffmpeg/ff_mpeg_parser.c b/src/combined/ffmpeg/ff_mpeg_parser.c new file mode 100644 index 000000000..70901d93b --- /dev/null +++ b/src/combined/ffmpeg/ff_mpeg_parser.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2001-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) + * based on libmpeg2 decoder. + */ +#define LOG_MODULE "mpeg_parser" +#define LOG_VERBOSE +/* +#define LOG +*/ +#include "ff_mpeg_parser.h" + +/* mpeg frame rate table from lavc */ +static const int frame_rate_tab[][2] = { + { 0, 0}, + {24000, 1001}, + { 24, 1}, + { 25, 1}, + {30000, 1001}, + { 30, 1}, + { 50, 1}, + {60000, 1001}, + { 60, 1}, + /* Xing's 15fps: (9) */ + { 15, 1}, + /* libmpeg3's "Unofficial economy rates": (10-13) */ + { 5, 1}, + { 10, 1}, + { 12, 1}, + { 15, 1}, + { 0, 0}, +}; + +void mpeg_parser_init (mpeg_parser_t *parser) +{ + parser->chunk_buffer = xine_xmalloc(BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); + mpeg_parser_reset(parser); +} + +void mpeg_parser_dispose (mpeg_parser_t *parser) +{ + if ( parser == NULL ) return; + + free(parser->chunk_buffer); +} + +void mpeg_parser_reset (mpeg_parser_t *parser) +{ + parser->shift = 0xffffff00; + parser->is_sequence_needed = 1; + parser->in_slice = 0; + parser->chunk_ptr = parser->chunk_buffer; + parser->chunk_start = parser->chunk_buffer; + parser->buffer_size = 0; + parser->code = 0xb4; + parser->picture_coding_type = 0; + parser->width = 0; + parser->height = 0; + parser->rate_code = 0; + parser->aspect_ratio_info = 0; + parser->frame_duration = 0; + parser->is_mpeg1 = 0; + parser->has_sequence = 0; + parser->frame_aspect_ratio = 0.0; +} + +static void parse_header_picture (mpeg_parser_t *parser, uint8_t * buffer) +{ + parser->picture_coding_type = (buffer [1] >> 3) & 7; +} + +static double get_aspect_ratio(mpeg_parser_t *parser) +{ + double ratio; + double mpeg1_pel_ratio[16] = {1.0 /* forbidden */, + 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, + 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ }; + + if( !parser->is_mpeg1 ) { + /* these hardcoded values are defined on mpeg2 standard for + * aspect ratio. other values are reserved or forbidden. */ + switch (parser->aspect_ratio_info) { + case 2: + ratio = 4.0 / 3.0; + break; + case 3: + ratio = 16.0 / 9.0; + break; + case 4: + ratio = 2.11 / 1.0; + break; + case 1: + default: + ratio = (double)parser->width / (double)parser->height; + break; + } + } else { + /* mpeg1 constants refer to pixel aspect ratio */ + ratio = (double)parser->width / (double)parser->height; + ratio /= mpeg1_pel_ratio[parser->aspect_ratio_info]; + } + + return ratio; +} + +static int parse_chunk (mpeg_parser_t *parser, int code, uint8_t *buffer, int len) +{ + int is_frame_done; + int next_code = parser->code; + + /* wait for sequence_header_code */ + if (parser->is_sequence_needed) { + if (code != 0xb3) { + lprintf("waiting for sequence header\n"); + parser->chunk_ptr = parser->chunk_buffer; + return 0; + } + } + + is_frame_done = parser->in_slice && ((!next_code) || (next_code == 0xb7)); + + if (is_frame_done) + parser->in_slice = 0; + + switch (code) { + case 0x00: /* picture_start_code */ + + parse_header_picture (parser, buffer); + + parser->in_slice = 1; + + switch (parser->picture_coding_type) { + case B_TYPE: + lprintf ("B-Frame\n"); + break; + + case P_TYPE: + lprintf ("P-Frame\n"); + break; + + case I_TYPE: + lprintf ("I-Frame\n"); + break; + } + break; + + case 0xb2: /* user data code */ + /* process_userdata(mpeg2dec, buffer); */ + break; + + case 0xb3: /* sequence_header_code */ + { + int value; + uint16_t width, height; + + if (parser->is_sequence_needed) { + parser->is_sequence_needed = 0; + } + + if ((buffer[6] & 0x20) != 0x20) { + lprintf("Invalid sequence: missing marker_bit\n"); + parser->has_sequence = 0; + break; /* missing marker_bit */ + } + + value = (buffer[0] << 16) | + (buffer[1] << 8) | + buffer[2]; + width = ((value >> 12) + 15) & ~15; + height = ((value & 0xfff) + 15) & ~15; + + if ((width > 1920) || (height > 1152)) { + lprintf("Invalid sequence: width=%d, height=%d\n", width, height); + parser->has_sequence = 0; + break; /* size restrictions for MP@HL */ + } + + parser->width = width; + parser->height = height; + parser->rate_code = buffer[3] & 15; + parser->aspect_ratio_info = buffer[3] >> 4; + + if (parser->rate_code < (sizeof(frame_rate_tab)/sizeof(*frame_rate_tab))) { + parser->frame_duration = 90000; + parser->frame_duration *= frame_rate_tab[parser->rate_code][1]; + parser->frame_duration /= frame_rate_tab[parser->rate_code][0]; + } else { + printf ("invalid/unknown frame rate code : %d \n", + parser->rate_code); + parser->frame_duration = 0; + } + + parser->has_sequence = 1; + parser->is_mpeg1 = 1; + } + break; + + case 0xb5: /* extension_start_code */ + switch (buffer[0] & 0xf0) { + case 0x10: /* sequence extension */ + parser->is_mpeg1 = 0; + } + + default: + if (code >= 0xb9) + lprintf ("stream not demultiplexed ?\n"); + + if (code >= 0xb0) + break; + } + return is_frame_done; +} + +static inline uint8_t *copy_chunk (mpeg_parser_t *parser, + uint8_t *current, uint8_t *end) +{ + uint32_t shift; + uint8_t *chunk_ptr; + uint8_t *limit; + uint8_t byte; + + shift = parser->shift; + chunk_ptr = parser->chunk_ptr; + + limit = current + (parser->chunk_buffer + BUFFER_SIZE - chunk_ptr); + if (limit > end) + limit = end; + + while (1) { + + byte = *current++; + *chunk_ptr++ = byte; + if (shift != 0x00000100) { + shift = (shift | byte) << 8; + if (current < limit) + continue; + if (current == end) { + parser->chunk_ptr = chunk_ptr; + parser->shift = shift; + lprintf("Need more bytes\n"); + return NULL; + } else { + /* we filled the chunk buffer without finding a start code */ + lprintf("Buffer full\n"); + parser->code = 0xb4; /* sequence_error_code */ + parser->chunk_ptr = parser->chunk_buffer; + return current; + } + } + lprintf("New chunk: 0x%2X\n", byte); + parser->chunk_ptr = chunk_ptr; + parser->shift = 0xffffff00; + parser->code = byte; + return current; + } +} + + +uint8_t *mpeg_parser_decode_data (mpeg_parser_t *parser, + uint8_t *current, uint8_t *end, + int *flush) +{ + int ret; + uint8_t code; + + ret = 0; + *flush = 0; + + while (current != end) { + if (parser->chunk_ptr == parser->chunk_buffer) { + /* write the beginning of the chunk */ + parser->chunk_buffer[0] = 0x00; + parser->chunk_buffer[1] = 0x00; + parser->chunk_buffer[2] = 0x01; + parser->chunk_buffer[3] = parser->code; + parser->chunk_ptr += 4; + parser->chunk_start = parser->chunk_ptr; + parser->has_sequence = 0; + } + + code = parser->code; + + current = copy_chunk (parser, current, end); + if (current == NULL) + return NULL; + ret = parse_chunk (parser, code, parser->chunk_start, + parser->chunk_ptr - parser->chunk_start - 4); + parser->chunk_start = parser->chunk_ptr; + if (ret == 1) { + if (parser->has_sequence) { + parser->frame_aspect_ratio = get_aspect_ratio(parser); + } + parser->buffer_size = parser->chunk_ptr - parser->chunk_buffer - 4; + parser->chunk_ptr = parser->chunk_buffer; + + if (parser->code == 0xb7) /* sequence end, maybe a still menu */ + *flush = 1; + + return current; + } + } + + return NULL; +} diff --git a/src/combined/ffmpeg/ff_mpeg_parser.h b/src/combined/ffmpeg/ff_mpeg_parser.h new file mode 100644 index 000000000..504e746f9 --- /dev/null +++ b/src/combined/ffmpeg/ff_mpeg_parser.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2001-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) + * based on libmpeg2 decoder. + */ +#ifndef HAVE_MPEG_PARSER_H +#define HAVE_MPEG_PARSER_H + +#include +#include "ffmpeg_decoder.h" + +#define BUFFER_SIZE (1194 * 1024) /* libmpeg2's buffer size */ + +/* picture coding type (mpeg2 header) */ +#define I_TYPE 1 +#define P_TYPE 2 +#define B_TYPE 3 +#define D_TYPE 4 + +typedef struct mpeg_parser_s { + uint8_t *chunk_buffer; + uint8_t *chunk_ptr; + uint8_t *chunk_start; + uint32_t shift; + int buffer_size; + uint8_t code; + uint8_t picture_coding_type; + + uint8_t is_sequence_needed:1; + uint8_t is_mpeg1:1; /* public */ + uint8_t has_sequence:1; /* public */ + uint8_t in_slice:1; + + uint8_t rate_code:4; + + int aspect_ratio_info; + + /* public properties */ + uint16_t width; + uint16_t height; + int frame_duration; + double frame_aspect_ratio; + +} mpeg_parser_t; + +/* parser initialization */ +void mpeg_parser_init (mpeg_parser_t *parser); + +/* parser disposal */ +void mpeg_parser_dispose (mpeg_parser_t *parser); + +/* read a frame + * return a pointer to the first byte of the next frame + * or NULL if more bytes are needed + * *flush is set to 1 if the decoder must be flushed (needed for still menus) + */ +uint8_t *mpeg_parser_decode_data (mpeg_parser_t *parser, + uint8_t *current, uint8_t *end, + int *flush); + +/* reset the parser */ +void mpeg_parser_reset (mpeg_parser_t *parser); + +#endif /* HAVE_MPEG_PARSER_H */ diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c new file mode 100644 index 000000000..4e5e1ebdf --- /dev/null +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -0,0 +1,1816 @@ +/* + * Copyright (C) 2001-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * xine video decoder plugin using ffmpeg + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +# ifndef HAVE_FFMPEG +# include "ffmpeg_config.h" +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "ffmpeg_video_dec" +#define LOG_VERBOSE +/* +#define LOG +*/ +#include +#include "bswap.h" +#include +#include +#include "ffmpeg_decoder.h" +#include "ff_mpeg_parser.h" + +#include + +#define VIDEOBUFSIZE (128*1024) +#define SLICE_BUFFER_SIZE (1194*1024) + +#define SLICE_OFFSET_SIZE 128 + +#define ENABLE_DIRECT_RENDERING + +typedef struct ff_video_decoder_s ff_video_decoder_t; + +typedef struct ff_video_class_s { + video_decoder_class_t decoder_class; + + int pp_quality; + int thread_count; + + xine_t *xine; +} ff_video_class_t; + +struct ff_video_decoder_s { + video_decoder_t video_decoder; + + ff_video_class_t *class; + + xine_stream_t *stream; + int64_t pts; + int video_step; + + uint8_t decoder_ok:1; + uint8_t decoder_init_mode:1; + uint8_t is_mpeg12:1; + uint8_t pp_available:1; + uint8_t yuv_init:1; + uint8_t is_direct_rendering_disabled:1; + uint8_t cs_convert_init:1; + uint8_t assume_bad_field_picture:1; + + xine_bmiheader bih; + unsigned char *buf; + int bufsize; + int size; + int skipframes; + + int slice_offset_size; + + AVFrame *av_frame; + AVCodecContext *context; + AVCodec *codec; + + int pp_quality; + int pp_flags; + pp_context_t *pp_context; + pp_mode_t *pp_mode; + + /* mpeg-es parsing */ + mpeg_parser_t *mpeg_parser; + + double aspect_ratio; + int aspect_ratio_prio; + int frame_flags; + int crop_right, crop_bottom; + + int output_format; + + xine_list_t *dr1_frames; + + yuv_planes_t yuv; + + AVPaletteControl palette_control; +}; + + +static void set_stream_info(ff_video_decoder_t *this) { + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->aspect_ratio * 10000); +} + +#ifdef ENABLE_DIRECT_RENDERING +/* called from ffmpeg to do direct rendering method 1 */ +static int get_buffer(AVCodecContext *context, AVFrame *av_frame){ + ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; + vo_frame_t *img; + int width = context->width; + int height = context->height; + + if (!this->bih.biWidth || !this->bih.biHeight) { + this->bih.biWidth = width; + this->bih.biHeight = height; + + if (this->aspect_ratio_prio == 0) { + this->aspect_ratio = (double)width / (double)height; + this->aspect_ratio_prio = 1; + lprintf("default aspect ratio: %f\n", this->aspect_ratio); + set_stream_info(this); + } + } + + avcodec_align_dimensions(context, &width, &height); + + if( this->context->pix_fmt != PIX_FMT_YUV420P ) { + if (!this->is_direct_rendering_disabled) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n")); + this->is_direct_rendering_disabled = 1; + } + + /* FIXME: why should i have to do that ? */ + av_frame->data[0]= NULL; + av_frame->data[1]= NULL; + av_frame->data[2]= NULL; + return avcodec_default_get_buffer(context, av_frame); + } + + if((width != this->bih.biWidth) || (height != this->bih.biHeight)) { + if(this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_CROP) { + this->crop_right = width - this->bih.biWidth; + this->crop_bottom = height - this->bih.biHeight; + } else { + if (!this->is_direct_rendering_disabled) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n")); + this->is_direct_rendering_disabled = 1; + } + /* FIXME: why should i have to do that ? */ + av_frame->data[0]= NULL; + av_frame->data[1]= NULL; + av_frame->data[2]= NULL; + return avcodec_default_get_buffer(context, av_frame); + } + } + + img = this->stream->video_out->get_frame (this->stream->video_out, + width, + height, + this->aspect_ratio, + this->output_format, + VO_BOTH_FIELDS|this->frame_flags); + + av_frame->opaque = img; + + av_frame->data[0]= img->base[0]; + av_frame->data[1]= img->base[1]; + av_frame->data[2]= img->base[2]; + + av_frame->linesize[0] = img->pitches[0]; + av_frame->linesize[1] = img->pitches[1]; + av_frame->linesize[2] = img->pitches[2]; + + /* We should really keep track of the ages of xine frames (see + * avcodec_default_get_buffer in libavcodec/utils.c) + * For the moment tell ffmpeg that every frame is new (age = bignumber) */ + av_frame->age = 256*256*256*64; + + av_frame->type= FF_BUFFER_TYPE_USER; + + xine_list_push_back(this->dr1_frames, av_frame); + + return 0; +} + +static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){ + ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; + + if (av_frame->type == FF_BUFFER_TYPE_USER) { + if ( av_frame->opaque ) { + vo_frame_t *img = (vo_frame_t *)av_frame->opaque; + + img->free(img); + } + + xine_list_iterator_t it; + + it = xine_list_find(this->dr1_frames, av_frame); + assert(it); + if( it != NULL ) + xine_list_remove(this->dr1_frames, it); + } else { + avcodec_default_release_buffer(context, av_frame); + } + + av_frame->opaque = NULL; + av_frame->data[0]= NULL; + av_frame->data[1]= NULL; + av_frame->data[2]= NULL; +} +#endif + +static const ff_codec_t ff_video_lookup[] = { + {BUF_VIDEO_MSMPEG4_V1, CODEC_ID_MSMPEG4V1, "Microsoft MPEG-4 v1 (ffmpeg)"}, + {BUF_VIDEO_MSMPEG4_V2, CODEC_ID_MSMPEG4V2, "Microsoft MPEG-4 v2 (ffmpeg)"}, + {BUF_VIDEO_MSMPEG4_V3, CODEC_ID_MSMPEG4V3, "Microsoft MPEG-4 v3 (ffmpeg)"}, + {BUF_VIDEO_WMV7, CODEC_ID_WMV1, "MS Windows Media Video 7 (ffmpeg)"}, + {BUF_VIDEO_WMV8, CODEC_ID_WMV2, "MS Windows Media Video 8 (ffmpeg)"}, + {BUF_VIDEO_WMV9, CODEC_ID_WMV3, "MS Windows Media Video 9 (ffmpeg)"}, + {BUF_VIDEO_VC1, CODEC_ID_VC1, "MS Windows Media Video VC-1 (ffmpeg)"}, + {BUF_VIDEO_MPEG4, CODEC_ID_MPEG4, "ISO MPEG-4 (ffmpeg)"}, + {BUF_VIDEO_XVID, CODEC_ID_MPEG4, "ISO MPEG-4 (XviD, ffmpeg)"}, + {BUF_VIDEO_DIVX5, CODEC_ID_MPEG4, "ISO MPEG-4 (DivX5, ffmpeg)"}, + {BUF_VIDEO_3IVX, CODEC_ID_MPEG4, "ISO MPEG-4 (3ivx, ffmpeg)"}, + {BUF_VIDEO_JPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"}, + {BUF_VIDEO_MJPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"}, + {BUF_VIDEO_MJPEG_B, CODEC_ID_MJPEGB, "Motion JPEG B (ffmpeg)"}, + {BUF_VIDEO_I263, CODEC_ID_H263I, "ITU H.263 (ffmpeg)"}, + {BUF_VIDEO_H263, CODEC_ID_H263, "H.263 (ffmpeg)"}, + {BUF_VIDEO_RV10, CODEC_ID_RV10, "Real Video 1.0 (ffmpeg)"}, + {BUF_VIDEO_RV20, CODEC_ID_RV20, "Real Video 2.0 (ffmpeg)"}, + {BUF_VIDEO_IV31, CODEC_ID_INDEO3, "Indeo Video 3.1 (ffmpeg)"}, + {BUF_VIDEO_IV32, CODEC_ID_INDEO3, "Indeo Video 3.2 (ffmpeg)"}, + {BUF_VIDEO_SORENSON_V1, CODEC_ID_SVQ1, "Sorenson Video 1 (ffmpeg)"}, + {BUF_VIDEO_SORENSON_V3, CODEC_ID_SVQ3, "Sorenson Video 3 (ffmpeg)"}, + {BUF_VIDEO_DV, CODEC_ID_DVVIDEO, "DV (ffmpeg)"}, + {BUF_VIDEO_HUFFYUV, CODEC_ID_HUFFYUV, "HuffYUV (ffmpeg)"}, + {BUF_VIDEO_VP31, CODEC_ID_VP3, "On2 VP3.1 (ffmpeg)"}, + {BUF_VIDEO_VP5, CODEC_ID_VP5, "On2 VP5 (ffmpeg)"}, + {BUF_VIDEO_VP6, CODEC_ID_VP6, "On2 VP6 (ffmpeg)"}, + {BUF_VIDEO_VP6F, CODEC_ID_VP6F, "On2 VP6 (ffmpeg)"}, + {BUF_VIDEO_4XM, CODEC_ID_4XM, "4X Video (ffmpeg)"}, + {BUF_VIDEO_CINEPAK, CODEC_ID_CINEPAK, "Cinepak (ffmpeg)"}, + {BUF_VIDEO_MSVC, CODEC_ID_MSVIDEO1, "Microsoft Video 1 (ffmpeg)"}, + {BUF_VIDEO_MSRLE, CODEC_ID_MSRLE, "Microsoft RLE (ffmpeg)"}, + {BUF_VIDEO_RPZA, CODEC_ID_RPZA, "Apple Quicktime Video/RPZA (ffmpeg)"}, + {BUF_VIDEO_CYUV, CODEC_ID_CYUV, "Creative YUV (ffmpeg)"}, + {BUF_VIDEO_ROQ, CODEC_ID_ROQ, "Id Software RoQ (ffmpeg)"}, + {BUF_VIDEO_IDCIN, CODEC_ID_IDCIN, "Id Software CIN (ffmpeg)"}, + {BUF_VIDEO_WC3, CODEC_ID_XAN_WC3, "Xan (ffmpeg)"}, + {BUF_VIDEO_VQA, CODEC_ID_WS_VQA, "Westwood Studios VQA (ffmpeg)"}, + {BUF_VIDEO_INTERPLAY, CODEC_ID_INTERPLAY_VIDEO, "Interplay MVE (ffmpeg)"}, + {BUF_VIDEO_FLI, CODEC_ID_FLIC, "FLIC Video (ffmpeg)"}, + {BUF_VIDEO_8BPS, CODEC_ID_8BPS, "Planar RGB (ffmpeg)"}, + {BUF_VIDEO_SMC, CODEC_ID_SMC, "Apple Quicktime Graphics/SMC (ffmpeg)"}, + {BUF_VIDEO_DUCKTM1, CODEC_ID_TRUEMOTION1,"Duck TrueMotion v1 (ffmpeg)"}, + {BUF_VIDEO_DUCKTM2, CODEC_ID_TRUEMOTION2,"Duck TrueMotion v2 (ffmpeg)"}, + {BUF_VIDEO_VMD, CODEC_ID_VMDVIDEO, "Sierra VMD Video (ffmpeg)"}, + {BUF_VIDEO_ZLIB, CODEC_ID_ZLIB, "ZLIB Video (ffmpeg)"}, + {BUF_VIDEO_MSZH, CODEC_ID_MSZH, "MSZH Video (ffmpeg)"}, + {BUF_VIDEO_ASV1, CODEC_ID_ASV1, "ASV v1 Video (ffmpeg)"}, + {BUF_VIDEO_ASV2, CODEC_ID_ASV2, "ASV v2 Video (ffmpeg)"}, + {BUF_VIDEO_ATIVCR1, CODEC_ID_VCR1, "ATI VCR-1 (ffmpeg)"}, + {BUF_VIDEO_FLV1, CODEC_ID_FLV1, "Flash Video (ffmpeg)"}, + {BUF_VIDEO_QTRLE, CODEC_ID_QTRLE, "Apple Quicktime Animation/RLE (ffmpeg)"}, + {BUF_VIDEO_H264, CODEC_ID_H264, "H.264/AVC (ffmpeg)"}, + {BUF_VIDEO_H261, CODEC_ID_H261, "H.261 (ffmpeg)"}, + {BUF_VIDEO_AASC, CODEC_ID_AASC, "Autodesk Video (ffmpeg)"}, + {BUF_VIDEO_LOCO, CODEC_ID_LOCO, "LOCO (ffmpeg)"}, + {BUF_VIDEO_QDRW, CODEC_ID_QDRAW, "QuickDraw (ffmpeg)"}, + {BUF_VIDEO_QPEG, CODEC_ID_QPEG, "Q-Team QPEG (ffmpeg)"}, + {BUF_VIDEO_TSCC, CODEC_ID_TSCC, "TechSmith Video (ffmpeg)"}, + {BUF_VIDEO_ULTI, CODEC_ID_ULTI, "IBM UltiMotion (ffmpeg)"}, + {BUF_VIDEO_WNV1, CODEC_ID_WNV1, "Winnow Video (ffmpeg)"}, + {BUF_VIDEO_XL, CODEC_ID_VIXL, "Miro/Pinnacle VideoXL (ffmpeg)"}, + {BUF_VIDEO_RT21, CODEC_ID_INDEO2, "Indeo/RealTime 2 (ffmpeg)"}, + {BUF_VIDEO_FPS1, CODEC_ID_FRAPS, "Fraps (ffmpeg)"}, + {BUF_VIDEO_MPEG, CODEC_ID_MPEG1VIDEO, "MPEG 1/2 (ffmpeg)"}, + {BUF_VIDEO_CSCD, CODEC_ID_CSCD, "CamStudio (ffmpeg)"}, + {BUF_VIDEO_AVS, CODEC_ID_AVS, "AVS (ffmpeg)"}, + {BUF_VIDEO_ALGMM, CODEC_ID_MMVIDEO, "American Laser Games MM (ffmpeg)"}, + {BUF_VIDEO_ZMBV, CODEC_ID_ZMBV, "Zip Motion Blocks Video (ffmpeg)"}, + {BUF_VIDEO_SMACKER, CODEC_ID_SMACKVIDEO, "Smacker (ffmpeg)"}, + {BUF_VIDEO_NUV, CODEC_ID_NUV, "NuppelVideo (ffmpeg)"}, + {BUF_VIDEO_KMVC, CODEC_ID_KMVC, "Karl Morton's Video Codec (ffmpeg)"}, + {BUF_VIDEO_FLASHSV, CODEC_ID_FLASHSV, "Flash Screen Video (ffmpeg)"}, + {BUF_VIDEO_CAVS, CODEC_ID_CAVS, "Chinese AVS (ffmpeg)"}, + {BUF_VIDEO_THEORA_RAW, CODEC_ID_THEORA, "Theora (ffmpeg)"}, +}; + + +static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) { + size_t i; + + /* find the decoder */ + this->codec = NULL; + + for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++) + if(ff_video_lookup[i].type == codec_type) { + pthread_mutex_lock(&ffmpeg_lock); + this->codec = avcodec_find_decoder(ff_video_lookup[i].id); + pthread_mutex_unlock(&ffmpeg_lock); + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, + ff_video_lookup[i].name); + break; + } + + if (!this->codec) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"), + codec_type); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + } + + lprintf("lavc decoder found\n"); + + /* force (width % 8 == 0), otherwise there will be + * display problems with Xv. + */ + this->bih.biWidth = (this->bih.biWidth + 1) & (~1); + + this->context->width = this->bih.biWidth; + this->context->height = this->bih.biHeight; + this->context->stream_codec_tag = this->context->codec_tag = + _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC); + + + /* Some codecs (eg rv10) copy flags in init so it's necessary to set + * this flag here in case we are going to use direct rendering */ + if(this->codec->capabilities & CODEC_CAP_DR1) { + this->context->flags |= CODEC_FLAG_EMU_EDGE; + } + + pthread_mutex_lock(&ffmpeg_lock); + if (avcodec_open (this->context, this->codec) < 0) { + pthread_mutex_unlock(&ffmpeg_lock); + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_video_dec: couldn't open decoder\n")); + free(this->context); + this->context = NULL; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + } + + if (this->class->thread_count > 1) { + avcodec_thread_init(this->context, this->class->thread_count); + this->context->thread_count = this->class->thread_count; + } + + pthread_mutex_unlock(&ffmpeg_lock); + + lprintf("lavc decoder opened\n"); + + this->decoder_ok = 1; + + if ((codec_type != BUF_VIDEO_MPEG) && + (codec_type != BUF_VIDEO_DV)) { + + if (!this->bih.biWidth || !this->bih.biHeight) { + this->bih.biWidth = this->context->width; + this->bih.biHeight = this->context->height; + } + + + set_stream_info(this); + } + + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + this->skipframes = 0; + + /* enable direct rendering by default */ + this->output_format = XINE_IMGFMT_YV12; +#ifdef ENABLE_DIRECT_RENDERING + if( this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264 ) { + this->context->get_buffer = get_buffer; + this->context->release_buffer = release_buffer; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_video_dec: direct rendering enabled\n")); + } +#endif + + /* flag for interlaced streams */ + this->frame_flags = 0; + /* FIXME: which codecs can be interlaced? + FIXME: check interlaced DCT and other codec specific info. */ + switch( codec_type ) { + case BUF_VIDEO_DV: + this->frame_flags |= VO_INTERLACED_FLAG; + break; + case BUF_VIDEO_MPEG: + this->frame_flags |= VO_INTERLACED_FLAG; + break; + case BUF_VIDEO_MJPEG: + this->frame_flags |= VO_INTERLACED_FLAG; + break; + case BUF_VIDEO_HUFFYUV: + this->frame_flags |= VO_INTERLACED_FLAG; + break; + case BUF_VIDEO_H264: + this->frame_flags |= VO_INTERLACED_FLAG; + break; + } + +} + +static void thread_count_cb(void *user_data, xine_cfg_entry_t *entry) { + ff_video_class_t *class = (ff_video_class_t *) user_data; + + class->thread_count = entry->num_value; +} + +static void pp_quality_cb(void *user_data, xine_cfg_entry_t *entry) { + ff_video_class_t *class = (ff_video_class_t *) user_data; + + class->pp_quality = entry->num_value; +} + +static void pp_change_quality (ff_video_decoder_t *this) { + this->pp_quality = this->class->pp_quality; + + if(this->pp_available && this->pp_quality) { + if(!this->pp_context && this->context) + this->pp_context = pp_get_context(this->context->width, this->context->height, + this->pp_flags); + if(this->pp_mode) + pp_free_mode(this->pp_mode); + + this->pp_mode = pp_get_mode_by_name_and_quality("hb:a,vb:a,dr:a", + this->pp_quality); + } else { + if(this->pp_mode) { + pp_free_mode(this->pp_mode); + this->pp_mode = NULL; + } + + if(this->pp_context) { + pp_free_context(this->pp_context); + this->pp_context = NULL; + } + } +} + +static void init_postprocess (ff_video_decoder_t *this) { + uint32_t cpu_caps; + + /* Allow post processing on mpeg-4 (based) codecs */ + switch(this->codec->id) { + case CODEC_ID_MPEG4: + case CODEC_ID_MSMPEG4V1: + case CODEC_ID_MSMPEG4V2: + case CODEC_ID_MSMPEG4V3: + case CODEC_ID_WMV1: + case CODEC_ID_WMV2: + this->pp_available = 1; + break; + default: + this->pp_available = 0; + break; + } + + /* Detect what cpu accel we have */ + cpu_caps = xine_mm_accel(); + this->pp_flags = PP_FORMAT_420; + + if(cpu_caps & MM_ACCEL_X86_MMX) + this->pp_flags |= PP_CPU_CAPS_MMX; + + if(cpu_caps & MM_ACCEL_X86_MMXEXT) + this->pp_flags |= PP_CPU_CAPS_MMX2; + + if(cpu_caps & MM_ACCEL_X86_3DNOW) + this->pp_flags |= PP_CPU_CAPS_3DNOW; + + /* Set level */ + pp_change_quality(this); +} + +static int ff_handle_mpeg_sequence(ff_video_decoder_t *this, mpeg_parser_t *parser) { + + /* + * init codec + */ + if (this->decoder_init_mode) { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, + "mpeg-1 (ffmpeg)"); + + init_video_codec (this, BUF_VIDEO_MPEG); + this->decoder_init_mode = 0; + } + + /* frame format change */ + if ((parser->width != this->bih.biWidth) || + (parser->height != this->bih.biHeight) || + (parser->frame_aspect_ratio != this->aspect_ratio)) { + xine_event_t event; + xine_format_change_data_t data; + + this->bih.biWidth = parser->width; + this->bih.biHeight = parser->height; + this->aspect_ratio = parser->frame_aspect_ratio; + this->aspect_ratio_prio = 2; + lprintf("mpeg seq aspect ratio: %f\n", this->aspect_ratio); + set_stream_info(this); + + event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; + event.stream = this->stream; + event.data = &data; + event.data_length = sizeof(data); + data.width = this->bih.biWidth; + data.height = this->bih.biHeight; + data.aspect = this->aspect_ratio; + data.pan_scan = 0; + xine_event_send(this->stream, &event); + } + this->video_step = this->mpeg_parser->frame_duration; + + return 1; +} + +static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { + int y; + uint8_t *dy, *du, *dv, *sy, *su, *sv; + + dy = img->base[0]; + du = img->base[1]; + dv = img->base[2]; + sy = this->av_frame->data[0]; + su = this->av_frame->data[1]; + sv = this->av_frame->data[2]; + + if (this->context->pix_fmt == PIX_FMT_YUV410P) { + + yuv9_to_yv12( + /* Y */ + this->av_frame->data[0], + this->av_frame->linesize[0], + img->base[0], + img->pitches[0], + /* U */ + this->av_frame->data[1], + this->av_frame->linesize[1], + img->base[1], + img->pitches[1], + /* V */ + this->av_frame->data[2], + this->av_frame->linesize[2], + img->base[2], + img->pitches[2], + /* width x height */ + img->width, + img->height); + + } else if (this->context->pix_fmt == PIX_FMT_YUV411P) { + + yuv411_to_yv12( + /* Y */ + this->av_frame->data[0], + this->av_frame->linesize[0], + img->base[0], + img->pitches[0], + /* U */ + this->av_frame->data[1], + this->av_frame->linesize[1], + img->base[1], + img->pitches[1], + /* V */ + this->av_frame->data[2], + this->av_frame->linesize[2], + img->base[2], + img->pitches[2], + /* width x height */ + img->width, + img->height); + + } else if (this->context->pix_fmt == PIX_FMT_RGBA32) { + + int x, plane_ptr = 0; + uint32_t *argb_pixels; + uint32_t argb; + + for(y = 0; y < img->height; y++) { + argb_pixels = (uint32_t *)sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; + + /* this is endian-safe as the ARGB pixels are stored in + * machine order */ + argb = *argb_pixels++; + r = (argb >> 16) & 0xFF; + g = (argb >> 8) & 0xFF; + b = (argb >> 0) & 0xFF; + + this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); + this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); + this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); + plane_ptr++; + } + sy += this->av_frame->linesize[0]; + } + + yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); + + } else if (this->context->pix_fmt == PIX_FMT_RGB565) { + + int x, plane_ptr = 0; + uint8_t *src; + uint16_t pixel16; + + for(y = 0; y < img->height; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; + + /* a 16-bit RGB565 pixel is supposed to be stored in native-endian + * byte order; the following should be endian-safe */ + pixel16 = *((uint16_t *)src); + src += 2; + b = (pixel16 << 3) & 0xFF; + g = (pixel16 >> 3) & 0xFF; + r = (pixel16 >> 8) & 0xFF; + + this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); + this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); + this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); + plane_ptr++; + } + sy += this->av_frame->linesize[0]; + } + + yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); + + } else if (this->context->pix_fmt == PIX_FMT_RGB555) { + + int x, plane_ptr = 0; + uint8_t *src; + uint16_t pixel16; + + for(y = 0; y < img->height; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; + + /* a 16-bit RGB555 pixel is supposed to be stored in native-endian + * byte order; the following should be endian-safe */ + pixel16 = *((uint16_t *)src); + src += 2; + b = (pixel16 << 3) & 0xFF; + g = (pixel16 >> 2) & 0xFF; + r = (pixel16 >> 7) & 0xFF; + + this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); + this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); + this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); + plane_ptr++; + } + sy += this->av_frame->linesize[0]; + } + + yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); + + } else if (this->context->pix_fmt == PIX_FMT_BGR24) { + + int x, plane_ptr = 0; + uint8_t *src; + + for(y = 0; y < img->height; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; + + b = *src++; + g = *src++; + r = *src++; + + this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); + this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); + this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); + plane_ptr++; + } + sy += this->av_frame->linesize[0]; + } + + yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); + + } else if (this->context->pix_fmt == PIX_FMT_RGB24) { + + int x, plane_ptr = 0; + uint8_t *src; + + for(y = 0; y < img->height; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; + + r = *src++; + g = *src++; + b = *src++; + + this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); + this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); + this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); + plane_ptr++; + } + sy += this->av_frame->linesize[0]; + } + + yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); + + } else if (this->context->pix_fmt == PIX_FMT_PAL8) { + + int x, plane_ptr = 0; + uint8_t *src; + uint8_t pixel; + uint32_t *palette32 = (uint32_t *)su; /* palette is in data[1] */ + uint32_t rgb_color; + uint8_t r, g, b; + uint8_t y_palette[256]; + uint8_t u_palette[256]; + uint8_t v_palette[256]; + + for (x = 0; x < 256; x++) { + rgb_color = palette32[x]; + b = rgb_color & 0xFF; + rgb_color >>= 8; + g = rgb_color & 0xFF; + rgb_color >>= 8; + r = rgb_color & 0xFF; + y_palette[x] = COMPUTE_Y(r, g, b); + u_palette[x] = COMPUTE_U(r, g, b); + v_palette[x] = COMPUTE_V(r, g, b); + } + + for(y = 0; y < img->height; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + pixel = *src++; + + this->yuv.y[plane_ptr] = y_palette[pixel]; + this->yuv.u[plane_ptr] = u_palette[pixel]; + this->yuv.v[plane_ptr] = v_palette[pixel]; + plane_ptr++; + } + sy += this->av_frame->linesize[0]; + } + + yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); + + } else { + + for (y=0; yheight; y++) { + xine_fast_memcpy (dy, sy, img->width); + + dy += img->pitches[0]; + + sy += this->av_frame->linesize[0]; + } + + for (y=0; y<(img->height/2); y++) { + + if (this->context->pix_fmt != PIX_FMT_YUV444P) { + + xine_fast_memcpy (du, su, img->width/2); + xine_fast_memcpy (dv, sv, img->width/2); + + } else { + + int x; + uint8_t *src; + uint8_t *dst; + + /* subsample */ + + src = su; dst = du; + for (x=0; x<(img->width/2); x++) { + *dst = *src; + dst++; + src += 2; + } + src = sv; dst = dv; + for (x=0; x<(img->width/2); x++) { + *dst = *src; + dst++; + src += 2; + } + + } + + du += img->pitches[1]; + dv += img->pitches[2]; + + if (this->context->pix_fmt != PIX_FMT_YUV420P) { + su += 2*this->av_frame->linesize[1]; + sv += 2*this->av_frame->linesize[2]; + } else { + su += this->av_frame->linesize[1]; + sv += this->av_frame->linesize[2]; + } + } + } +} + +static void ff_check_bufsize (ff_video_decoder_t *this, int size) { + if (size > this->bufsize) { + this->bufsize = size + size / 2; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n"), + this->bufsize); + this->buf = realloc(this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE ); + } +} + +static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { + int codec_type; + + lprintf ("preview buffer\n"); + + codec_type = buf->type & 0xFFFF0000; + if (codec_type == BUF_VIDEO_MPEG) { + this->is_mpeg12 = 1; + if ( this->mpeg_parser == NULL ) { + this->mpeg_parser = xine_xmalloc(sizeof(mpeg_parser_t)); + mpeg_parser_init(this->mpeg_parser); + this->decoder_init_mode = 0; + } + } + + if (this->decoder_init_mode && !this->is_mpeg12) { + init_video_codec(this, codec_type); + init_postprocess(this); + this->decoder_init_mode = 0; + } +} + +static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *buf) { + + lprintf ("header buffer\n"); + + /* accumulate data */ + ff_check_bufsize(this, this->size + buf->size); + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + int codec_type; + + lprintf ("header complete\n"); + codec_type = buf->type & 0xFFFF0000; + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { + + lprintf("standard header\n"); + + /* init package containing bih */ + memcpy ( &this->bih, this->buf, sizeof(xine_bmiheader) ); + + if (this->bih.biSize > sizeof(xine_bmiheader)) { + this->context->extradata_size = this->bih.biSize - sizeof(xine_bmiheader); + this->context->extradata = malloc(this->context->extradata_size + + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(this->context->extradata, this->buf + sizeof(xine_bmiheader), + this->context->extradata_size); + } + + this->context->bits_per_sample = this->bih.biBitCount; + + } else { + + switch (codec_type) { + case BUF_VIDEO_RV10: + case BUF_VIDEO_RV20: + this->bih.biWidth = _X_BE_16(&this->buf[12]); + this->bih.biHeight = _X_BE_16(&this->buf[14]); + + this->context->sub_id = _X_BE_32(&this->buf[30]); + + this->context->slice_offset = xine_xmalloc(sizeof(int)*SLICE_OFFSET_SIZE); + this->slice_offset_size = SLICE_OFFSET_SIZE; + + lprintf("w=%d, h=%d\n", this->bih.biWidth, this->bih.biHeight); + + break; + default: + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_video_dec: unknown header for buf type 0x%X\n", codec_type); + return; + } + } + + /* reset accumulator */ + this->size = 0; + } +} + +static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *buf) { + /* take care of all the various types of special buffers + * note that order is important here */ + lprintf("special buffer\n"); + + if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM && + !this->context->extradata_size) { + + lprintf("BUF_SPECIAL_STSD_ATOM\n"); + this->context->extradata_size = buf->decoder_info[2]; + this->context->extradata = xine_xmalloc(buf->decoder_info[2] + + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(this->context->extradata, buf->decoder_info_ptr[2], + buf->decoder_info[2]); + + } else if (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG && + !this->context->extradata_size) { + + lprintf("BUF_SPECIAL_DECODER_CONFIG\n"); + this->context->extradata_size = buf->decoder_info[2]; + this->context->extradata = xine_xmalloc(buf->decoder_info[2] + + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(this->context->extradata, buf->decoder_info_ptr[2], + buf->decoder_info[2]); + + } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) { + unsigned int i; + + palette_entry_t *demuxer_palette; + AVPaletteControl *decoder_palette; + + lprintf("BUF_SPECIAL_PALETTE\n"); + this->context->palctrl = &this->palette_control; + decoder_palette = (AVPaletteControl *)this->context->palctrl; + demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2]; + + for (i = 0; i < buf->decoder_info[2]; i++) { + decoder_palette->palette[i] = + (demuxer_palette[i].r << 16) | + (demuxer_palette[i].g << 8) | + (demuxer_palette[i].b << 0); + } + decoder_palette->palette_changed = 1; + + } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) { + int i; + + lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n"); + this->context->slice_count = buf->decoder_info[2]+1; + + lprintf("slice_count=%d\n", this->context->slice_count); + + if(this->context->slice_count > this->slice_offset_size) { + this->context->slice_offset = realloc(this->context->slice_offset, + sizeof(int)*this->context->slice_count); + this->slice_offset_size = this->context->slice_count; + } + + for(i = 0; i < this->context->slice_count; i++) { + this->context->slice_offset[i] = + ((uint32_t *) buf->decoder_info_ptr[2])[(2*i)+1]; + lprintf("slice_offset[%d]=%d\n", i, this->context->slice_offset[i]); + } + } +} + +static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *buf) { + + vo_frame_t *img; + int free_img; + int got_picture, len; + int offset = 0; + int flush = 0; + int size = buf->size; + + lprintf("handle_mpeg12_buffer\n"); + + while ((size > 0) || (flush == 1)) { + + uint8_t *current; + int next_flush; + + got_picture = 0; + if (!flush) { + current = mpeg_parser_decode_data(this->mpeg_parser, + buf->content + offset, buf->content + offset + size, + &next_flush); + } else { + current = buf->content + offset + size; /* end of the buffer */ + next_flush = 0; + } + if (current == NULL) { + lprintf("current == NULL\n"); + return; + } + + if (this->mpeg_parser->has_sequence) { + ff_handle_mpeg_sequence(this, this->mpeg_parser); + } + + if (!this->decoder_ok) + return; + + if (flush) { + lprintf("flush lavc buffers\n"); + /* hack: ffmpeg outputs the last frame if size=0 */ + this->mpeg_parser->buffer_size = 0; + } + + /* skip decoding b frames if too late */ + this->context->hurry_up = (this->skipframes > 0); + + lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser->buffer_size); + len = avcodec_decode_video (this->context, this->av_frame, + &got_picture, this->mpeg_parser->chunk_buffer, + this->mpeg_parser->buffer_size); + lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n", + len, got_picture); + len = current - buf->content - offset; + lprintf("avcodec_decode_video: consumed_size=%d\n", len); + + flush = next_flush; + + if ((len < 0) || (len > buf->size)) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_video_dec: error decompressing frame\n"); + size = 0; /* draw a bad frame and exit */ + } else { + size -= len; + offset += len; + } + + if (got_picture && this->av_frame->data[0]) { + /* got a picture, draw it */ + if(!this->av_frame->opaque) { + /* indirect rendering */ + img = this->stream->video_out->get_frame (this->stream->video_out, + this->bih.biWidth, + this->bih.biHeight, + this->aspect_ratio, + this->output_format, + VO_BOTH_FIELDS|this->frame_flags); + free_img = 1; + } else { + /* DR1 */ + img = (vo_frame_t*) this->av_frame->opaque; + free_img = 0; + } + + img->pts = this->pts; + this->pts = 0; + + if (this->av_frame->repeat_pict) + img->duration = this->video_step * 3 / 2; + else + img->duration = this->video_step; + + img->crop_right = this->crop_right; + img->crop_bottom = this->crop_bottom; + + this->skipframes = img->draw(img, this->stream); + + if(free_img) + img->free(img); + + } else { + + if (this->context->hurry_up) { + /* skipped frame, output a bad frame */ + img = this->stream->video_out->get_frame (this->stream->video_out, + this->bih.biWidth, + this->bih.biHeight, + this->aspect_ratio, + this->output_format, + VO_BOTH_FIELDS|this->frame_flags); + img->pts = 0; + img->duration = this->video_step; + img->bad_frame = 1; + this->skipframes = img->draw(img, this->stream); + img->free(img); + } + } + } +} + +static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { + uint8_t *chunk_buf = this->buf; + AVRational avr00 = {0, 1}; + + lprintf("handle_buffer\n"); + + if (!this->decoder_ok) { + if (this->decoder_init_mode) { + int codec_type = buf->type & 0xFFFF0000; + + /* init ffmpeg decoder */ + init_video_codec(this, codec_type); + init_postprocess(this); + this->decoder_init_mode = 0; + } else { + return; + } + } + + if (buf->decoder_flags & BUF_FLAG_FRAME_START) { + lprintf("BUF_FLAG_FRAME_START\n"); + this->size = 0; + } + + /* data accumulation */ + if (buf->size > 0) { + if ((this->size == 0) && + ((buf->size + FF_INPUT_BUFFER_PADDING_SIZE) < buf->max_size) && + (buf->decoder_flags & BUF_FLAG_FRAME_END)) { + /* buf contains a complete frame */ + /* no memcpy needed */ + chunk_buf = buf->content; + this->size = buf->size; + lprintf("no memcpy needed to accumulate data\n"); + } else { + /* copy data into our internal buffer */ + ff_check_bufsize(this, this->size + buf->size); + chunk_buf = this->buf; /* ff_check_bufsize might realloc this->buf */ + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + lprintf("accumulate data into this->buf\n"); + } + } + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + vo_frame_t *img; + int free_img; + int got_picture, len; + int got_one_picture = 0; + int offset = 0; + int codec_type = buf->type & 0xFFFF0000; + int video_step_to_use; + + /* pad input data */ + /* note: bitstream, alt bitstream reader or something will cause + * severe mpeg4 artifacts if padding is less than 32 bits. + */ + memset(&chunk_buf[this->size], 0, FF_INPUT_BUFFER_PADDING_SIZE); + + while (this->size > 0) { + + /* DV frames can be completely skipped */ + if( codec_type == BUF_VIDEO_DV && this->skipframes ) { + this->size = 0; + got_picture = 0; + } else { + /* skip decoding b frames if too late */ + this->context->hurry_up = (this->skipframes > 0); + + lprintf("buffer size: %d\n", this->size); + len = avcodec_decode_video (this->context, this->av_frame, + &got_picture, &chunk_buf[offset], + this->size); + lprintf("consumed size: %d, got_picture: %d\n", len, got_picture); + if ((len <= 0) || (len > this->size)) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_video_dec: error decompressing frame\n"); + this->size = 0; + + } else { + + offset += len; + this->size -= len; + + if (this->size > 0) { + ff_check_bufsize(this, this->size); + memmove (this->buf, &chunk_buf[offset], this->size); + chunk_buf = this->buf; + } + } + } + + /* use externally provided video_step or fall back to stream's time_base otherwise */ + video_step_to_use = (this->video_step || !this->context->time_base.den) ? this->video_step : (int)(90000ll * this->context->time_base.num / this->context->time_base.den); + + /* aspect ratio provided by ffmpeg, override previous setting */ + if ((this->aspect_ratio_prio < 2) && + av_cmp_q(this->context->sample_aspect_ratio, avr00)) { + + if (!this->bih.biWidth || !this->bih.biHeight) { + this->bih.biWidth = this->context->width; + this->bih.biHeight = this->context->height; + } + + this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * + (double)this->bih.biWidth / (double)this->bih.biHeight; + this->aspect_ratio_prio = 2; + lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio); + set_stream_info(this); + } + + if (got_picture && this->av_frame->data[0]) { + /* got a picture, draw it */ + got_one_picture = 1; + if(!this->av_frame->opaque) { + /* indirect rendering */ + + /* initialize the colorspace converter */ + if (!this->cs_convert_init) { + if ((this->context->pix_fmt == PIX_FMT_RGBA32) || + (this->context->pix_fmt == PIX_FMT_RGB565) || + (this->context->pix_fmt == PIX_FMT_RGB555) || + (this->context->pix_fmt == PIX_FMT_BGR24) || + (this->context->pix_fmt == PIX_FMT_RGB24) || + (this->context->pix_fmt == PIX_FMT_PAL8)) { + this->output_format = XINE_IMGFMT_YUY2; + init_yuv_planes(&this->yuv, this->bih.biWidth, this->bih.biHeight); + this->yuv_init = 1; + } + this->cs_convert_init = 1; + } + + if (this->aspect_ratio_prio == 0) { + this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; + this->aspect_ratio_prio = 1; + lprintf("default aspect ratio: %f\n", this->aspect_ratio); + set_stream_info(this); + } + + /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */ + img = this->stream->video_out->get_frame (this->stream->video_out, + (this->bih.biWidth + 15) & ~15, + (this->bih.biHeight + 15) & ~15, + this->aspect_ratio, + this->output_format, + VO_BOTH_FIELDS|this->frame_flags); + free_img = 1; + } else { + /* DR1 */ + img = (vo_frame_t*) this->av_frame->opaque; + free_img = 0; + } + + /* post processing */ + if(this->pp_quality != this->class->pp_quality) + pp_change_quality(this); + + if(this->pp_available && this->pp_quality) { + + if(this->av_frame->opaque) { + /* DR1 */ + img = this->stream->video_out->get_frame (this->stream->video_out, + (img->width + 15) & ~15, + (img->height + 15) & ~15, + this->aspect_ratio, + this->output_format, + VO_BOTH_FIELDS|this->frame_flags); + free_img = 1; + } + + pp_postprocess(this->av_frame->data, this->av_frame->linesize, + img->base, img->pitches, + img->width, img->height, + this->av_frame->qscale_table, this->av_frame->qstride, + this->pp_mode, this->pp_context, + this->av_frame->pict_type); + + } else if (!this->av_frame->opaque) { + /* colorspace conversion or copy */ + ff_convert_frame(this, img); + } + + img->pts = this->pts; + this->pts = 0; + + /* workaround for weird 120fps streams */ + if( video_step_to_use == 750 ) { + /* fallback to the VIDEO_PTS_MODE */ + video_step_to_use = 0; + } + + if (this->av_frame->repeat_pict) + img->duration = video_step_to_use * 3 / 2; + else + img->duration = video_step_to_use; + + /* additionally crop away the extra pixels due to adjusting frame size above */ + img->crop_right = this->crop_right + (img->width - this->bih.biWidth); + img->crop_bottom = this->crop_bottom + (img->height - this->bih.biHeight); + + /* transfer some more frame settings for deinterlacing */ + img->progressive_frame = !this->av_frame->interlaced_frame; + img->top_field_first = this->av_frame->top_field_first; + + this->skipframes = img->draw(img, this->stream); + + if(free_img) + img->free(img); + } + } + + /* workaround for demux_mpeg_pes sending fields as frames: + * do not generate a bad frame for the first field picture + */ + if (!got_one_picture && (this->size || this->video_step || this->assume_bad_field_picture)) { + /* skipped frame, output a bad frame (use size 16x16, when size still uninitialized) */ + img = this->stream->video_out->get_frame (this->stream->video_out, + (this->bih.biWidth <= 0) ? 16 : ((this->bih.biWidth + 15) & ~15), + (this->bih.biHeight <= 0) ? 16 : ((this->bih.biHeight + 15) & ~15), + this->aspect_ratio, + this->output_format, + VO_BOTH_FIELDS|this->frame_flags); + /* set PTS to allow early syncing */ + img->pts = this->pts; + this->pts = 0; + + img->duration = video_step_to_use; + + /* additionally crop away the extra pixels due to adjusting frame size above */ + img->crop_right = ((this->bih.biWidth <= 0) ? 0 : this->crop_right) + (img->width - this->bih.biWidth); + img->crop_bottom = ((this->bih.biHeight <= 0) ? 0 : this->crop_bottom) + (img->height - this->bih.biHeight); + + img->bad_frame = 1; + this->skipframes = img->draw(img, this->stream); + img->free(img); + } + + this->assume_bad_field_picture = !got_one_picture; + } +} + +static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; + + lprintf ("processing packet type = %08x, len = %d, decoder_flags=%08x\n", + buf->type, buf->size, buf->decoder_flags); + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_PREVIEW) { + + ff_handle_preview_buffer(this, buf); + + } else { + + if (buf->decoder_flags & BUF_FLAG_SPECIAL) { + + ff_handle_special_buffer(this, buf); + + } + + if (buf->decoder_flags & BUF_FLAG_HEADER) { + + ff_handle_header_buffer(this, buf); + + if (buf->decoder_flags & BUF_FLAG_ASPECT) { + if (this->aspect_ratio_prio < 3) { + this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; + this->aspect_ratio_prio = 3; + lprintf("aspect ratio: %f\n", this->aspect_ratio); + set_stream_info(this); + } + } + + } else { + + /* decode */ + if (buf->pts) + this->pts = buf->pts; + + if (this->is_mpeg12) { + ff_handle_mpeg12_buffer(this, buf); + } else { + ff_handle_buffer(this, buf); + } + + } + } +} + +static void ff_flush (video_decoder_t *this_gen) { + lprintf ("ff_flush\n"); +} + +static void ff_reset (video_decoder_t *this_gen) { + ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; + + lprintf ("ff_reset\n"); + + this->size = 0; + + if(this->context && this->decoder_ok) + avcodec_flush_buffers(this->context); + + if (this->is_mpeg12) + mpeg_parser_reset(this->mpeg_parser); +} + +static void ff_discontinuity (video_decoder_t *this_gen) { + ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; + + lprintf ("ff_discontinuity\n"); + this->pts = 0; +} + +static void ff_dispose (video_decoder_t *this_gen) { + ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; + + lprintf ("ff_dispose\n"); + + if (this->decoder_ok) { + xine_list_iterator_t it; + AVFrame *av_frame; + + pthread_mutex_lock(&ffmpeg_lock); + avcodec_close (this->context); + pthread_mutex_unlock(&ffmpeg_lock); + + /* frame garbage collector here - workaround for buggy ffmpeg codecs that + * don't release their DR1 frames */ + while( (it = xine_list_front(this->dr1_frames)) != NULL ) + { + av_frame = (AVFrame *)xine_list_get_value(this->dr1_frames, it); + release_buffer(this->context, av_frame); + } + + this->stream->video_out->close(this->stream->video_out, this->stream); + this->decoder_ok = 0; + } + + if(this->context && this->context->slice_offset) + free(this->context->slice_offset); + + if(this->context && this->context->extradata) + free(this->context->extradata); + + if(this->yuv_init) + free_yuv_planes(&this->yuv); + + if( this->context ) + free( this->context ); + + if( this->av_frame ) + free( this->av_frame ); + + if (this->buf) + free(this->buf); + this->buf = NULL; + + if(this->pp_context) + pp_free_context(this->pp_context); + + if(this->pp_mode) + pp_free_mode(this->pp_mode); + + mpeg_parser_dispose(this->mpeg_parser); + + xine_list_delete(this->dr1_frames); + + free (this_gen); +} + +static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + ff_video_decoder_t *this ; + + lprintf ("open_plugin\n"); + + this = (ff_video_decoder_t *) xine_xmalloc (sizeof (ff_video_decoder_t)); + + this->video_decoder.decode_data = ff_decode_data; + this->video_decoder.flush = ff_flush; + this->video_decoder.reset = ff_reset; + this->video_decoder.discontinuity = ff_discontinuity; + this->video_decoder.dispose = ff_dispose; + this->size = 0; + + this->stream = stream; + this->class = (ff_video_class_t *) class_gen; + + this->av_frame = avcodec_alloc_frame(); + this->context = avcodec_alloc_context(); + this->context->opaque = this; + this->context->palctrl = NULL; + + this->decoder_ok = 0; + this->decoder_init_mode = 1; + this->buf = xine_xmalloc(VIDEOBUFSIZE + FF_INPUT_BUFFER_PADDING_SIZE); + this->bufsize = VIDEOBUFSIZE; + + this->is_mpeg12 = 0; + this->aspect_ratio = 0; + + this->pp_quality = 0; + this->pp_context = NULL; + this->pp_mode = NULL; + + this->mpeg_parser = NULL; + + this->dr1_frames = xine_list_new(); + + return &this->video_decoder; +} + +void *init_video_plugin (xine_t *xine, void *data) { + + ff_video_class_t *this; + config_values_t *config; + + this = (ff_video_class_t *) xine_xmalloc (sizeof (ff_video_class_t)); + + this->decoder_class.open_plugin = ff_video_open_plugin; + this->decoder_class.identifier = "ffmpeg video"; + this->decoder_class.description = N_("ffmpeg based video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + this->xine = xine; + + pthread_once( &once_control, init_once_routine ); + + /* Configuration for post processing quality - default to mid (3) for the + * moment */ + config = xine->config; + + this->pp_quality = xine->config->register_range(config, "video.processing.ffmpeg_pp_quality", 3, + 0, PP_QUALITY_MAX, + _("MPEG-4 postprocessing quality"), + _("You can adjust the amount of post processing applied to MPEG-4 video.\n" + "Higher values result in better quality, but need more CPU. Lower values may " + "result in image defects like block artifacts. For high quality content, " + "too heavy post processing can actually make the image worse by blurring it " + "too much."), + 10, pp_quality_cb, this); + + this->thread_count = xine->config->register_num(config, "video.processing.ffmpeg_thread_count", 1, + _("FFmpeg video decoding thread count"), + _("You can adjust the number of video decoding threads which FFmpeg may use.\n" + "Higher values should speed up decoding but it depends on the codec used " + "whether parallel decoding is supported. A rule of thumb is to have one " + "decoding thread per logical CPU (typically 1 to 4). A change will take " + "effect with playing the next stream."), + 10, thread_count_cb, this); + + return this; +} + +static uint32_t supported_video_types[] = { +#if defined(HAVE_FFMPEG) || CONFIG_MSMPEG4V1_DECODER + BUF_VIDEO_MSMPEG4_V1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MSMPEG4V2_DECODER + BUF_VIDEO_MSMPEG4_V2, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MSMPEG4V3_DECODER + BUF_VIDEO_MSMPEG4_V3, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WMV1_DECODER + BUF_VIDEO_WMV7, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WMV2_DECODER + BUF_VIDEO_WMV8, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WMV3_DECODER + BUF_VIDEO_WMV9, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VC1_DECODER + BUF_VIDEO_VC1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER + BUF_VIDEO_MPEG4, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER + BUF_VIDEO_XVID, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER + BUF_VIDEO_DIVX5, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER + BUF_VIDEO_3IVX, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MJPEG_DECODER + BUF_VIDEO_JPEG, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MJPEG_DECODER + BUF_VIDEO_MJPEG, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MJPEGB_DECODER + BUF_VIDEO_MJPEG_B, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_H263I_DECODER + BUF_VIDEO_I263, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_H263_DECODER + BUF_VIDEO_H263, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_RV10_DECODER + BUF_VIDEO_RV10, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_RV20_DECODER + BUF_VIDEO_RV20, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_INDEO3_DECODER + BUF_VIDEO_IV31, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_INDEO3_DECODER + BUF_VIDEO_IV32, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_SVQ1_DECODER + BUF_VIDEO_SORENSON_V1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_SVQ3_DECODER + BUF_VIDEO_SORENSON_V3, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_DVVIDEO_DECODER + BUF_VIDEO_DV, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_HUFFYUV_DECODER + BUF_VIDEO_HUFFYUV, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VP3_DECODER + BUF_VIDEO_VP31, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VP5_DECODER + BUF_VIDEO_VP5, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VP6_DECODER + BUF_VIDEO_VP6, + BUF_VIDEO_VP6F, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_4XM_DECODER + BUF_VIDEO_4XM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_CINEPAK_DECODER + BUF_VIDEO_CINEPAK, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MSVIDEO1_DECODER + BUF_VIDEO_MSVC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MSRLE_DECODER + BUF_VIDEO_MSRLE, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_RPZA_DECODER + BUF_VIDEO_RPZA, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_CYUV_DECODER + BUF_VIDEO_CYUV, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ROQ_DECODER + BUF_VIDEO_ROQ, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_IDCIN_DECODER + BUF_VIDEO_IDCIN, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_XAN_WC3_DECODER + BUF_VIDEO_WC3, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WS_VQA_DECODER + BUF_VIDEO_VQA, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_INTERPLAY_VIDEO_DECODER + BUF_VIDEO_INTERPLAY, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_FLIC_DECODER + BUF_VIDEO_FLI, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_8BPS_DECODER + BUF_VIDEO_8BPS, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_SMC_DECODER + BUF_VIDEO_SMC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_TRUEMOTION1_DECODER + BUF_VIDEO_DUCKTM1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_TRUEMOTION2_DECODER + BUF_VIDEO_DUCKTM2, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VMDVIDEO_DECODER + BUF_VIDEO_VMD, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ZLIB_DECODER + BUF_VIDEO_ZLIB, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MSZH_DECODER + BUF_VIDEO_MSZH, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ASV1_DECODER + BUF_VIDEO_ASV1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ASV2_DECODER + BUF_VIDEO_ASV2, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VCR1_DECODER + BUF_VIDEO_ATIVCR1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_FLV_DECODER + BUF_VIDEO_FLV1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_QTRLE_DECODER + BUF_VIDEO_QTRLE, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_H264_DECODER + BUF_VIDEO_H264, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_H261_DECODER + BUF_VIDEO_H261, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_AASC_DECODER + BUF_VIDEO_AASC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_LOCO_DECODER + BUF_VIDEO_LOCO, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_QDRAW_DECODER + BUF_VIDEO_QDRW, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_QPEG_DECODER + BUF_VIDEO_QPEG, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_TSCC_DECODER + BUF_VIDEO_TSCC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ULTI_DECODER + BUF_VIDEO_ULTI, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_WNV1_DECODER + BUF_VIDEO_WNV1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_VIXL_DECODER + BUF_VIDEO_XL, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_INDEO2_DECODER + BUF_VIDEO_RT21, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_FRAPS_DECODER + BUF_VIDEO_FPS1, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MPEG1VIDEO_DECODER + BUF_VIDEO_MPEG, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_CSCD_DECODER + BUF_VIDEO_CSCD, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_AVS_DECODER + BUF_VIDEO_AVS, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_MMVIDEO_DECODER + BUF_VIDEO_ALGMM, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_ZMBV_DECODER + BUF_VIDEO_ZMBV, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_SMACKVIDEO_DECODER + BUF_VIDEO_SMACKER, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_NUV_DECODER + BUF_VIDEO_NUV, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_KMVC_DECODER + BUF_VIDEO_KMVC, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_FLASHSV_DECODER + BUF_VIDEO_FLASHSV, +#endif +#if defined(HAVE_FFMPEG) || CONFIG_CAVS_DECODER + BUF_VIDEO_CAVS, +#endif + BUF_VIDEO_THEORA_RAW, + 0 +}; + +static uint32_t wmv8_video_types[] = { + BUF_VIDEO_WMV8, + 0 +}; + +static uint32_t wmv9_video_types[] = { + BUF_VIDEO_WMV9, + 0 +}; + +decoder_info_t dec_info_ffmpeg_video = { + supported_video_types, /* supported types */ + 6 /* priority */ +}; + +decoder_info_t dec_info_ffmpeg_wmv8 = { + wmv8_video_types, /* supported types */ + 0 /* priority */ +}; + +decoder_info_t dec_info_ffmpeg_wmv9 = { + wmv9_video_types, /* supported types */ + 0 /* priority */ +}; diff --git a/src/combined/ffmpeg/ffmpeg_decoder.c b/src/combined/ffmpeg/ffmpeg_decoder.c new file mode 100644 index 000000000..8a8a79270 --- /dev/null +++ b/src/combined/ffmpeg/ffmpeg_decoder.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2001-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * xine decoder plugin using ffmpeg + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "ffmpeg_decoder.h" + +/* + * common initialisation + */ + +pthread_once_t once_control = PTHREAD_ONCE_INIT; +pthread_mutex_t ffmpeg_lock; + +void init_once_routine(void) { + pthread_mutex_init(&ffmpeg_lock, NULL); + avcodec_init(); + avcodec_register_all(); +} + +/* + * exported plugin catalog entry + */ + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 19, "ffmpegvideo", XINE_VERSION_CODE, &dec_info_ffmpeg_video, init_video_plugin }, + { PLUGIN_VIDEO_DECODER, 19, "ffmpeg-wmv8", XINE_VERSION_CODE, &dec_info_ffmpeg_wmv8, init_video_plugin }, + { PLUGIN_VIDEO_DECODER, 19, "ffmpeg-wmv9", XINE_VERSION_CODE, &dec_info_ffmpeg_wmv9, init_video_plugin }, + { PLUGIN_AUDIO_DECODER, 16, "ffmpegaudio", XINE_VERSION_CODE, &dec_info_ffmpeg_audio, init_audio_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/combined/ffmpeg/ffmpeg_decoder.h b/src/combined/ffmpeg/ffmpeg_decoder.h new file mode 100644 index 000000000..bfe71a6b1 --- /dev/null +++ b/src/combined/ffmpeg/ffmpeg_decoder.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2001-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +#ifndef HAVE_XINE_DECODER_H +#define HAVE_XINE_DECODER_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +typedef struct ff_codec_s { + uint32_t type; + enum CodecID id; + const char *name; +} ff_codec_t; + +void *init_audio_plugin (xine_t *xine, void *data); +void *init_video_plugin (xine_t *xine, void *data); + +extern decoder_info_t dec_info_ffmpeg_video; +extern decoder_info_t dec_info_ffmpeg_wmv8; +extern decoder_info_t dec_info_ffmpeg_wmv9; +extern decoder_info_t dec_info_ffmpeg_audio; + +extern pthread_once_t once_control; +void init_once_routine(void); + +extern pthread_mutex_t ffmpeg_lock; + +#endif diff --git a/src/combined/ffmpeg/ffmpeg_encoder.c b/src/combined/ffmpeg/ffmpeg_encoder.c new file mode 100644 index 000000000..7fe65c7fa --- /dev/null +++ b/src/combined/ffmpeg/ffmpeg_encoder.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +/* mpeg encoders for the dxr3 video out plugin. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "dxr3_mpeg_encoder" +/* #define LOG_VERBOSE */ +/* #define LOG */ + +#include "video_out_dxr3.h" + +#include + +/* buffer size for encoded mpeg1 stream; will hold one intra frame + * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ +#define DEFAULT_BUFFER_SIZE 512*1024 + + +/*initialisation function, used by the dxr3 plugin */ +int dxr3_encoder_init(dxr3_driver_t *drv) EXPORTED; + +/* functions required by encoder api */ +static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame); +static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame); +static int lavc_on_unneeded(dxr3_driver_t *drv); + +/*encoder structure*/ +typedef struct lavc_data_s { + encoder_data_t encoder_data; + AVCodecContext *context; /* handle for encoding */ + int width, height; /* width and height of the video frame */ + uint8_t *ffmpeg_buffer; /* lavc buffer */ + AVFrame *picture; /* picture to be encoded */ + uint8_t *out[3]; /* aligned buffer for YV12 data */ + uint8_t *buf; /* unaligned YV12 buffer */ +} lavc_data_t; + + +int dxr3_encoder_init(dxr3_driver_t *drv) +{ + lavc_data_t* this; + avcodec_init(); + + avcodec_register_all(); + lprintf("lavc init , version %x\n", avcodec_version()); + this = xine_xmalloc(sizeof(lavc_data_t)); + if (!this) return 0; + + this->encoder_data.type = ENC_LAVC; + this->encoder_data.on_update_format = lavc_on_update_format; + this->encoder_data.on_frame_copy = NULL; + this->encoder_data.on_display_frame = lavc_on_display_frame; + this->encoder_data.on_unneeded = lavc_on_unneeded; + this->context = 0; + + drv->enc = &this->encoder_data; + return 1; +} + +/* helper function */ +static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame); + +static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) +{ + lavc_data_t *this = (lavc_data_t *)drv->enc; + AVCodec *codec; + unsigned char use_quantizer; + + if (this->context) { + avcodec_close(this->context); + free(this->context); + free(this->picture); + this->context = NULL; + this->picture = NULL; + } + + /* if YUY2 and dimensions changed, we need to re-allocate the + * internal YV12 buffer */ + if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { + int image_size = frame->vo_frame.pitches[0] * frame->oheight; + + this->out[0] = xine_xmalloc_aligned(16, image_size * 3/2, + (void *)&this->buf); + this->out[1] = this->out[0] + image_size; + this->out[2] = this->out[1] + image_size/4; + + /* fill with black (yuv 16,128,128) */ + memset(this->out[0], 16, image_size); + memset(this->out[1], 128, image_size/4); + memset(this->out[2], 128, image_size/4); + lprintf("Using YUY2->YV12 conversion\n"); + } + + /* resolution must be a multiple of two */ + if ((frame->vo_frame.pitches[0] % 2 != 0) || (frame->oheight % 2 != 0)) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: lavc only handles video dimensions which are multiples of 2\n"); + return 0; + } + + /* get mpeg codec handle */ + codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); + if (!codec) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: lavc MPEG1 codec not found\n"); + return 0; + } + lprintf("lavc MPEG1 encoder found.\n"); + + this->width = frame->vo_frame.pitches[0]; + this->height = frame->oheight; + + this->context = avcodec_alloc_context(); + if (!this->context) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't start the ffmpeg library\n"); + return 0; + } + this->picture = avcodec_alloc_frame(); + if (!this->picture) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't allocate ffmpeg frame\n"); + return 0; + } + + /* mpeg1 encoder only support YUV420P */ + this->context->pix_fmt = PIX_FMT_YUVJ420P; + + /* put sample parameters */ + this->context->bit_rate = drv->class->xine->config->register_range(drv->class->xine->config, + "dxr3.encoding.lavc_bitrate", 10000, 1000, 20000, + _("libavcodec mpeg output bitrate (kbit/s)"), + _("The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " + "Higher values will increase quality and CPU usage.\n" + "This setting is only considered, when constant quality mode is disabled."), 10, NULL, NULL); + this->context->bit_rate *= 1000; /* config in kbit/s, libavcodec wants bit/s */ + + use_quantizer = drv->class->xine->config->register_bool(drv->class->xine->config, + "dxr3.encoding.lavc_quantizer", 1, + _("constant quality mode"), + _("When enabled, libavcodec will use a constant quality mode by dynamically " + "compressing the images based on their complexity. When disabled, libavcodec " + "will use constant bitrate mode."), 10, NULL, NULL); + + if (use_quantizer) { + this->context->qmin = drv->class->xine->config->register_range(drv->class->xine->config, + "dxr3.encoding.lavc_qmin", 1, 1, 10, + _("minimum compression"), + _("The minimum compression to apply to an image in constant quality mode."), + 10, NULL, NULL); + + this->context->qmax = drv->class->xine->config->register_range(drv->class->xine->config, + "dxr3.encoding.lavc_qmax", 2, 1, 20, + _("maximum quantizer"), + _("The maximum compression to apply to an image in constant quality mode."), + 10, NULL, NULL); + } + + lprintf("lavc -> bitrate %d \n", this->context->bit_rate); + + this->context->width = frame->vo_frame.pitches[0]; + this->context->height = frame->oheight; + + this->context->gop_size = 0; /*intra frames only */ + this->context->me_method = ME_ZERO; /*motion estimation type*/ + + this->context->time_base.den = 90000; + if (frame->vo_frame.duration > 90000 / 24) + this->context->time_base.num = 90000 / 24; + else if (frame->vo_frame.duration < 90000 / 60) + this->context->time_base.num = 90000 / 60; + else + this->context->time_base.num = frame->vo_frame.duration; + /* ffmpeg can complain about illegal framerates, but since this seems no + * problem for the DXR3, we just tell ffmpeg to be more lax with */ + this->context->strict_std_compliance = -1; + + /* open avcodec */ + if (avcodec_open(this->context, codec) < 0) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: could not open codec\n"); + return 0; + } + lprintf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n"); + + if (!this->ffmpeg_buffer) + this->ffmpeg_buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); /* why allocate more than needed ?! */ + if (!this->ffmpeg_buffer) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); + return 0; + } + + return 1; +} + +static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) +{ + int size; + lavc_data_t* this = (lavc_data_t *)drv->enc; + ssize_t written; + + if (frame->vo_frame.bad_frame) return 1; + /* ignore old frames */ + if ((frame->vo_frame.pitches[0] != this->context->width) || (frame->oheight != this->context->height)) { + frame->vo_frame.free(&frame->vo_frame); + lprintf("LAVC ignoring frame !!!\n"); + return 1; + } + + /* prepare frame for conversion, handles YUY2 -> YV12 conversion when necessary */ + lavc_prepare_frame(this, drv, frame); + + /* do the encoding */ + size = avcodec_encode_video(this->context, this->ffmpeg_buffer, DEFAULT_BUFFER_SIZE, this->picture); + + frame->vo_frame.free(&frame->vo_frame); + + if (size < 0) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: encoding failed\n"); + return 0; + } + + written = write(drv->fd_video, this->ffmpeg_buffer, size); + if (written < 0) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); + return 0; + } + if (written != size) + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, size); + return 1; +} + +static int lavc_on_unneeded(dxr3_driver_t *drv) +{ + lavc_data_t *this = (lavc_data_t *)drv->enc; + lprintf("flushing buffers\n"); + if (this->context) { + avcodec_close(this->context); + free(this->context); + free(this->picture); + this->context = NULL; + this->picture = NULL; + } + return 1; +} + +static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame) +{ + int i, j, w2; + uint8_t *yuy2; + + if (frame->vo_frame.bad_frame) return 1; + + if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { + /* need YUY2->YV12 conversion */ + if (!(this->out[0] && this->out[1] && this->out[2]) ) { + lprintf("Internal YV12 buffer not created.\n"); + return 0; + } + this->picture->data[0] = this->out[0] + frame->vo_frame.pitches[0] * drv->top_bar; /* y */ + this->picture->data[1] = this->out[1] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* u */ + this->picture->data[2] = this->out[2] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* v */ + yuy2 = frame->vo_frame.base[0]; + w2 = frame->vo_frame.pitches[0] / 2; + for (i = 0; i < frame->vo_frame.height; i += 2) { + for (j = 0; j < w2; j++) { + /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */ + *(this->picture->data[0]++) = *(yuy2++); + *(this->picture->data[1]++) = *(yuy2++); + *(this->picture->data[0]++) = *(yuy2++); + *(this->picture->data[2]++) = *(yuy2++); + } + /* down sampling */ + for (j = 0; j < w2; j++) { + /* skip every second line for U and V */ + *(this->picture->data[0]++) = *(yuy2++); + yuy2++; + *(this->picture->data[0]++) = *(yuy2++); + yuy2++; + } + } + /* reset for encoder */ + this->picture->data[0] = this->out[0]; + this->picture->data[1] = this->out[1]; + this->picture->data[2] = this->out[2]; + } + else { /* YV12 **/ + this->picture->data[0] = frame->real_base[0]; + this->picture->data[1] = frame->real_base[1]; + this->picture->data[2] = frame->real_base[2]; + } + this->picture->linesize[0] = this->context->width; + this->picture->linesize[1] = this->context->width / 2; + this->picture->linesize[2] = this->context->width / 2; + return 1; +} diff --git a/src/libffmpeg/Makefile.am b/src/libffmpeg/Makefile.am deleted file mode 100644 index 42fe20f95..000000000 --- a/src/libffmpeg/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_CPPFLAGS = $(ZLIB_CPPFLAGS) -AM_LDFLAGS = $(xineplug_ldflags) - -if WITH_EXTERNAL_FFMPEG -AM_CFLAGS += $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS) -link_ffmpeg = $(FFMPEG_LIBS) $(FFMPEG_POSTPROC_LIBS) -else -AM_CPPFLAGS += -I$(top_srcdir)/contrib/ffmpeg/libavutil \ - -I$(top_srcdir)/contrib/ffmpeg/libavcodec \ - -I$(top_srcdir)/contrib/ffmpeg/libpostproc -link_ffmpeg = $(top_builddir)/contrib/ffmpeg/libavcodec/libavcodec.a \ - $(top_builddir)/contrib/ffmpeg/libavutil/libavutil.a \ - $(top_builddir)/contrib/ffmpeg/libpostproc/libpostproc.a - -$(top_builddir)/contrib/ffmpeg/libavcodec/libavcodec.a: - $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/libavcodec/libavcodec.a - -$(top_builddir)/contrib/ffmpeg/libavutil/libavutil.a: - $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/libavutil/libavutil.a - -$(top_builddir)/contrib/ffmpeg/libpostproc/libpostproc.a: - $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/libpostproc/libpostproc.a - -$(top_builddir)/contrib/ffmpeg/config.h: - $(MAKE) -C $(top_builddir)/contrib/ ffmpeg/config.mak - -ffmpeg_config.h: $(top_builddir)/contrib/ffmpeg/config.h - cp $(top_builddir)/contrib/ffmpeg/config.h ffmpeg_config.h - -BUILT_SOURCES = ffmpeg_config.h -CLEANFILES = $(BUILT_SOURCES) - -endif - -# this must always be included, even if the current machine has no DXR3... -EXTRA_DIST = ffmpeg_encoder.c - -xineplug_LTLIBRARIES = xineplug_decode_ff.la xineplug_decode_dvaudio.la - -if ENABLE_DXR3 -AM_CFLAGS += $(X_CFLAGS) -AM_CPPFLAGS += -I$(top_srcdir)/src/dxr3 -xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \ - ffmpeg_encoder.c ff_mpeg_parser.c ffmpeg_decoder.h \ - ff_mpeg_parser.h -else -xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \ - ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h -endif - -nodist_xineplug_decode_ff_la_SOURCES = ffmpeg_config.h - -xineplug_decode_ff_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) -lm $(ZLIB_LIBS) \ - $(link_ffmpeg) $(PTHREAD_LIBS) $(LTLIBINTL) -xineplug_decode_ff_la_LDFLAGS = $(AM_LDFLAGS) $(IMPURE_TEXT_LDFLAGS) - -xineplug_decode_dvaudio_la_SOURCES = ff_dvaudio_decoder.c -xineplug_decode_dvaudio_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) -xineplug_decode_dvaudio_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/contrib/ffmpeg/libavcodec diff --git a/src/libffmpeg/ff_audio_decoder.c b/src/libffmpeg/ff_audio_decoder.c deleted file mode 100644 index dd03cd2a3..000000000 --- a/src/libffmpeg/ff_audio_decoder.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright (C) 2001-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine audio decoder plugin using ffmpeg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -# ifndef HAVE_FFMPEG -# include "ffmpeg_config.h" -# endif -#endif - -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "ffmpeg_audio_dec" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include "bswap.h" -#include "ffmpeg_decoder.h" - -#define AUDIOBUFSIZE (64 * 1024) - -typedef struct { - audio_decoder_class_t decoder_class; -} ff_audio_class_t; - -typedef struct ff_audio_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - int output_open; - int audio_channels; - int audio_bits; - int audio_sample_rate; - - unsigned char *buf; - int bufsize; - int size; - - AVCodecContext *context; - AVCodec *codec; - - char *decode_buffer; - int decoder_ok; - -} ff_audio_decoder_t; - - -static const ff_codec_t ff_audio_lookup[] = { - {BUF_AUDIO_WMAV1, CODEC_ID_WMAV1, "MS Windows Media Audio 1 (ffmpeg)"}, - {BUF_AUDIO_WMAV2, CODEC_ID_WMAV2, "MS Windows Media Audio 2 (ffmpeg)"}, - {BUF_AUDIO_14_4, CODEC_ID_RA_144, "Real 14.4 (ffmpeg)"}, - {BUF_AUDIO_28_8, CODEC_ID_RA_288, "Real 28.8 (ffmpeg)"}, - {BUF_AUDIO_MPEG, CODEC_ID_MP3, "MP3 (ffmpeg)"}, - {BUF_AUDIO_MSADPCM, CODEC_ID_ADPCM_MS, "MS ADPCM (ffmpeg)"}, - {BUF_AUDIO_QTIMAADPCM, CODEC_ID_ADPCM_IMA_QT, "QT IMA ADPCM (ffmpeg)"}, - {BUF_AUDIO_MSIMAADPCM, CODEC_ID_ADPCM_IMA_WAV, "MS IMA ADPCM (ffmpeg)"}, - {BUF_AUDIO_DK3ADPCM, CODEC_ID_ADPCM_IMA_DK3, "Duck DK3 ADPCM (ffmpeg)"}, - {BUF_AUDIO_DK4ADPCM, CODEC_ID_ADPCM_IMA_DK4, "Duck DK4 ADPCM (ffmpeg)"}, - {BUF_AUDIO_VQA_IMA, CODEC_ID_ADPCM_IMA_WS, "Westwood Studios IMA (ffmpeg)"}, - {BUF_AUDIO_SMJPEG_IMA, CODEC_ID_ADPCM_IMA_SMJPEG, "SMJPEG IMA (ffmpeg)"}, - {BUF_AUDIO_XA_ADPCM, CODEC_ID_ADPCM_XA, "CD-ROM/XA ADPCM (ffmpeg)"}, - {BUF_AUDIO_4X_ADPCM, CODEC_ID_ADPCM_4XM, "4X ADPCM (ffmpeg)"}, - {BUF_AUDIO_EA_ADPCM, CODEC_ID_ADPCM_EA, "Electronic Arts ADPCM (ffmpeg)"}, - {BUF_AUDIO_MULAW, CODEC_ID_PCM_MULAW, "mu-law logarithmic PCM (ffmpeg)"}, - {BUF_AUDIO_ALAW, CODEC_ID_PCM_ALAW, "A-law logarithmic PCM (ffmpeg)"}, - {BUF_AUDIO_ROQ, CODEC_ID_ROQ_DPCM, "RoQ DPCM (ffmpeg)"}, - {BUF_AUDIO_INTERPLAY, CODEC_ID_INTERPLAY_DPCM, "Interplay DPCM (ffmpeg)"}, - {BUF_AUDIO_MAC3, CODEC_ID_MACE3, "MACE 3:1 (ffmpeg)"}, - {BUF_AUDIO_MAC6, CODEC_ID_MACE6, "MACE 6:1 (ffmpeg)"}, - {BUF_AUDIO_XAN_DPCM, CODEC_ID_XAN_DPCM, "Origin Xan DPCM (ffmpeg)"}, - {BUF_AUDIO_VMD, CODEC_ID_VMDAUDIO, "Sierra VMD Audio (ffmpeg)"}, - {BUF_AUDIO_FLAC, CODEC_ID_FLAC, "FLAC (ffmpeg)"}, - {BUF_AUDIO_SHORTEN, CODEC_ID_SHORTEN, "Shorten (ffmpeg)"}, - {BUF_AUDIO_ALAC, CODEC_ID_ALAC, "ALAC (ffmpeg)"}, - {BUF_AUDIO_QDESIGN2, CODEC_ID_QDM2, "QDesign (ffmpeg)"}, - {BUF_AUDIO_COOK, CODEC_ID_COOK, "RealAudio Cooker (ffmpeg)"}, - {BUF_AUDIO_TRUESPEECH, CODEC_ID_TRUESPEECH, "TrueSpeech (ffmpeg)"}, - {BUF_AUDIO_TTA, CODEC_ID_TTA, "True Audio Lossless (ffmpeg)"}, - {BUF_AUDIO_SMACKER, CODEC_ID_SMACKAUDIO, "Smacker (ffmpeg)"}, - {BUF_AUDIO_FLVADPCM, CODEC_ID_ADPCM_SWF, "Flash ADPCM (ffmpeg)"}, - {BUF_AUDIO_WAVPACK, CODEC_ID_WAVPACK, "WavPack (ffmpeg)"}, -}; - - - static void ff_audio_ensure_buffer_size(ff_audio_decoder_t *this, int size) { - if (size > this->bufsize) { - this->bufsize = size + size / 2; - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), - this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); - } -} - -static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen; - int bytes_consumed; - int decode_buffer_size; - int offset; - int out; - audio_buffer_t *audio_buffer; - int bytes_to_send; - - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_SPECIAL) ) { - - /* accumulate init data */ - ff_audio_ensure_buffer_size(this, this->size + buf->size); - memcpy(this->buf + this->size, buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - size_t i; - unsigned int codec_type; - xine_waveformatex *audio_header; - - codec_type = buf->type & 0xFFFF0000; - this->codec = NULL; - - for(i = 0; i < sizeof(ff_audio_lookup)/sizeof(ff_codec_t); i++) - if(ff_audio_lookup[i].type == codec_type) { - pthread_mutex_lock (&ffmpeg_lock); - this->codec = avcodec_find_decoder(ff_audio_lookup[i].id); - pthread_mutex_unlock (&ffmpeg_lock); - _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, - ff_audio_lookup[i].name); - break; - } - - if (!this->codec) { - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"), - codec_type); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - return; - } - - this->context = avcodec_alloc_context(); - - if(buf->decoder_flags & BUF_FLAG_STDHEADER) { - this->audio_sample_rate = buf->decoder_info[1]; - this->audio_channels = buf->decoder_info[3]; - - if(this->size) { - audio_header = (xine_waveformatex *)this->buf; - - this->context->block_align = audio_header->nBlockAlign; - this->context->bit_rate = audio_header->nAvgBytesPerSec * 8; - - if(audio_header->cbSize > 0) { - this->context->extradata = xine_xmalloc(audio_header->cbSize); - this->context->extradata_size = audio_header->cbSize; - memcpy( this->context->extradata, - (uint8_t *)audio_header + sizeof(xine_waveformatex), - audio_header->cbSize ); - } - } - } else { - short *ptr; - - switch(codec_type) { - case BUF_AUDIO_14_4: - this->audio_sample_rate = 8000; - this->audio_channels = 1; - - this->context->block_align = 240; - break; - case BUF_AUDIO_28_8: - this->audio_sample_rate = _X_BE_16(&this->buf[0x30]); - this->audio_channels = this->buf[0x37]; - /* this->audio_bits = buf->content[0x35] */ - - this->context->block_align = _X_BE_16(&this->buf[0x2A]); - - this->context->extradata_size = 5*sizeof(short); - this->context->extradata = xine_xmalloc(this->context->extradata_size); - - ptr = (short *) this->context->extradata; - - ptr[0] = _X_BE_16(&this->buf[0x2C]); /* subpacket size */ - ptr[1] = _X_BE_16(&this->buf[0x28]); /* subpacket height */ - ptr[2] = _X_BE_16(&this->buf[0x16]); /* subpacket flavour */ - ptr[3] = _X_BE_32(&this->buf[0x18]); /* coded frame size */ - ptr[4] = 0; /* codec's data length */ - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type); - break; - } - } - - /* Current ffmpeg audio decoders always use 16 bits/sample - * buf->decoder_info[2] can't be used as it doesn't refer to the output - * bits/sample for some codecs (e.g. MS ADPCM) */ - this->audio_bits = 16; - - this->context->bits_per_sample = this->audio_bits; - this->context->sample_rate = this->audio_sample_rate; - this->context->channels = this->audio_channels; - this->context->codec_id = this->codec->id; - this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC); - - this->size = 0; - - this->decode_buffer = xine_xmalloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); - - return; - } - } else if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && - (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM)) { - - this->context->extradata_size = buf->decoder_info[2]; - this->context->extradata = xine_xmalloc(buf->decoder_info[2] + - FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(this->context->extradata, buf->decoder_info_ptr[2], - buf->decoder_info[2]); - - } else if (!(buf->decoder_flags & BUF_FLAG_SPECIAL)) { - - if( !this->decoder_ok ) { - if ( ! this->context || ! this->codec ) { - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_audio_dec: trying to open null codec\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - return; - } - - pthread_mutex_lock (&ffmpeg_lock); - if (avcodec_open (this->context, this->codec) < 0) { - pthread_mutex_unlock (&ffmpeg_lock); - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_audio_dec: couldn't open decoder\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); - return; - } - pthread_mutex_unlock (&ffmpeg_lock); - this->decoder_ok = 1; - } - - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, this->audio_bits, this->audio_sample_rate, - _x_ao_channels2mode(this->audio_channels)); - } - - /* if the audio still isn't open, bail */ - if (!this->output_open) - return; - - if( buf->decoder_flags & BUF_FLAG_PREVIEW ) - return; - - ff_audio_ensure_buffer_size(this, this->size + buf->size); - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ - - offset = 0; - while (this->size>0) { - decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; - bytes_consumed = avcodec_decode_audio2 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, - &this->buf[offset], - this->size); - - if (bytes_consumed<0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_audio_dec: error decompressing audio frame\n"); - this->size=0; - return; - } else if (bytes_consumed == 0 && decode_buffer_size == 0) { - if (offset) - memmove(this->buf, &this->buf[offset], this->size); - return; - } - - /* dispatch the decoded audio */ - out = 0; - while (out < decode_buffer_size) { - audio_buffer = - this->stream->audio_out->get_buffer (this->stream->audio_out); - if (audio_buffer->mem_size == 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_audio_dec: Help! Allocated audio buffer with nothing in it!\n"); - return; - } - - if ((decode_buffer_size - out) > audio_buffer->mem_size) - bytes_to_send = audio_buffer->mem_size; - else - bytes_to_send = decode_buffer_size - out; - - /* fill up this buffer */ - xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out], - bytes_to_send); - /* byte count / 2 (bytes / sample) / channels */ - audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels; - - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, - audio_buffer, this->stream); - - out += bytes_to_send; - } - - this->size -= bytes_consumed; - offset += bytes_consumed; - } - - /* reset internal accumulation buffer */ - this->size = 0; - } - } -} - -static void ff_audio_reset (audio_decoder_t *this_gen) { - ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen; - - this->size = 0; - - /* try to reset the wma decoder */ - if( this->context && this->decoder_ok ) { - pthread_mutex_lock (&ffmpeg_lock); - avcodec_close (this->context); - avcodec_open (this->context, this->codec); - pthread_mutex_unlock (&ffmpeg_lock); - } -} - -static void ff_audio_discontinuity (audio_decoder_t *this_gen) { -} - -static void ff_audio_dispose (audio_decoder_t *this_gen) { - - ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen; - - if( this->context && this->decoder_ok ) { - pthread_mutex_lock (&ffmpeg_lock); - avcodec_close (this->context); - pthread_mutex_unlock (&ffmpeg_lock); - } - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - free(this->buf); - free(this->decode_buffer); - - if(this->context && this->context->extradata) - free(this->context->extradata); - - if(this->context) - free(this->context); - - free (this_gen); -} - -static audio_decoder_t *ff_audio_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - ff_audio_decoder_t *this ; - - this = (ff_audio_decoder_t *) xine_xmalloc (sizeof (ff_audio_decoder_t)); - - this->audio_decoder.decode_data = ff_audio_decode_data; - this->audio_decoder.reset = ff_audio_reset; - this->audio_decoder.discontinuity = ff_audio_discontinuity; - this->audio_decoder.dispose = ff_audio_dispose; - - this->output_open = 0; - this->audio_channels = 0; - this->stream = stream; - this->buf = NULL; - this->size = 0; - this->bufsize = 0; - this->decoder_ok = 0; - - ff_audio_ensure_buffer_size(this, AUDIOBUFSIZE); - - return &this->audio_decoder; -} - -void *init_audio_plugin (xine_t *xine, void *data) { - - ff_audio_class_t *this ; - - this = (ff_audio_class_t *) xine_xmalloc (sizeof (ff_audio_class_t)); - - this->decoder_class.open_plugin = ff_audio_open_plugin; - this->decoder_class.identifier = "ffmpeg audio"; - this->decoder_class.description = N_("ffmpeg based audio decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - pthread_once( &once_control, init_once_routine ); - - return this; -} - -static uint32_t supported_audio_types[] = { -#if defined(HAVE_FFMPEG) || CONFIG_WMAV1_DECODER - BUF_AUDIO_WMAV1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WMAV2_DECODER - BUF_AUDIO_WMAV2, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_RA_144_DECODER - BUF_AUDIO_14_4, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_RA_288_DECODER - BUF_AUDIO_28_8, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MP3_DECODER - BUF_AUDIO_MPEG, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_MS_DECODER - BUF_AUDIO_MSADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_QT_DECODER - BUF_AUDIO_QTIMAADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_WAV_DECODER - BUF_AUDIO_MSIMAADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_DK3_DECODER - BUF_AUDIO_DK3ADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_DK4_DECODER - BUF_AUDIO_DK4ADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_WS_DECODER - BUF_AUDIO_VQA_IMA, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_IMA_SMJPEG_DECODER - BUF_AUDIO_SMJPEG_IMA, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_XA_DECODER - BUF_AUDIO_XA_ADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_4XM_DECODER - BUF_AUDIO_4X_ADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_EA_DECODER - BUF_AUDIO_EA_ADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_PCM_MULAW_DECODER - BUF_AUDIO_MULAW, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_PCM_ALAW_DECODER - BUF_AUDIO_ALAW, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ROQ_DPCM_DECODER - BUF_AUDIO_ROQ, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_INTERPLAY_DPCM_DECODER - BUF_AUDIO_INTERPLAY, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MACE3_DECODER - BUF_AUDIO_MAC3, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MACE6_DECODER - BUF_AUDIO_MAC6, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_XAN_DPCM_DECODER - BUF_AUDIO_XAN_DPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VMDAUDIO_DECODER - BUF_AUDIO_VMD, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_FLAC_DECODER - BUF_AUDIO_FLAC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_SHORTEN_DECODER - BUF_AUDIO_SHORTEN, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ALAC_DECODER - BUF_AUDIO_ALAC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_QDM2_DECODER - BUF_AUDIO_QDESIGN2, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_COOK_DECODER - BUF_AUDIO_COOK, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_TRUESPEECH_DECODER - BUF_AUDIO_TRUESPEECH, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_TTA_DECODER - BUF_AUDIO_TTA, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_SMACKAUDIO_DECODER - BUF_AUDIO_SMACKER, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ADPCM_SWF_DECODER - BUF_AUDIO_FLVADPCM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WAVPACK_DECODER - BUF_AUDIO_WAVPACK, -#endif - - 0 -}; - -decoder_info_t dec_info_ffmpeg_audio = { - supported_audio_types, /* supported types */ - 6 /* priority */ -}; diff --git a/src/libffmpeg/ff_dvaudio_decoder.c b/src/libffmpeg/ff_dvaudio_decoder.c deleted file mode 100644 index aced7f5bb..000000000 --- a/src/libffmpeg/ff_dvaudio_decoder.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * dv audio decoder based on patch by Dan Dennedy - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#define LOG_MODULE "dvaudio" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include - -#ifdef _MSC_VER -/* ffmpeg has own definitions of those types */ -# undef int8_t -# undef uint8_t -# undef int16_t -# undef uint16_t -# undef int32_t -# undef uint32_t -# undef int64_t -# undef uint64_t -#endif - -#include -#include /* This is not installed by FFmpeg, its usage has to be cleared up */ - -#ifdef _MSC_VER -# undef malloc -# undef free -# undef realloc -#endif - -#define AUDIOBUFSIZE 128*1024 -#define MAXFRAMESIZE 131072 - - -typedef struct { - audio_decoder_class_t decoder_class; -} dvaudio_class_t; - -typedef struct dvaudio_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - int output_open; - int audio_channels; - int audio_bits; - int audio_sample_rate; - - unsigned char *buf; - int bufsize; - int size; - - char *decode_buffer; - int decoder_ok; - -} dvaudio_decoder_t; - -/* - * This is the dumbest implementation of all -- it simply looks at - * a fixed offset and if pack isn't there -- fails. We might want - * to have a fallback mechanism for complete search of missing packs. - */ -static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) -{ - int offs; - - switch (t) { - case dv_audio_source: - offs = (80*6 + 80*16*3 + 3); - break; - case dv_audio_control: - offs = (80*6 + 80*16*4 + 3); - break; - case dv_video_control: - offs = (80*5 + 48 + 5); - break; - default: - return NULL; - } - - return (frame[offs] == t ? &frame[offs] : NULL); -} - -static inline uint16_t dv_audio_12to16(uint16_t sample) -{ - uint16_t shift, result; - - sample = (sample < 0x800) ? sample : sample | 0xf000; - shift = (sample & 0xf00) >> 8; - - if (shift < 0x2 || shift > 0xd) { - result = sample; - } else if (shift < 0x8) { - shift--; - result = (sample - (256 * shift)) << shift; - } else { - shift = 0xe - shift; - result = ((sample + ((256 * shift) + 1)) << shift) - 1; - } - - return result; -} - -/* - * There's a couple of assumptions being made here: - * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. - * We can pass them upwards when ffmpeg will be ready to deal with them. - * 2. We don't do software emphasis. - * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples - * are converted into 16bit linear ones. - */ -static int dv_extract_audio(uint8_t* frame, uint8_t* pcm, uint8_t* pcm2) -{ - int size, i, j, d, of, smpls, freq, quant, half_ch; - uint16_t lc, rc; - const DVprofile* sys; - const uint8_t* as_pack; - - as_pack = dv_extract_pack(frame, dv_audio_source); - if (!as_pack) /* No audio ? */ - return 0; - - sys = dv_frame_profile(frame); - smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ - freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */ - quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ - - if (quant > 1) - return -1; /* Unsupported quantization */ - - size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ - half_ch = sys->difseg_size/2; - - /* for each DIF segment */ - for (i = 0; i < sys->difseg_size; i++) { - frame += 6 * 80; /* skip DIF segment header */ - if (quant == 1 && i == half_ch) { - if (!pcm2) - break; - else - pcm = pcm2; - } - - for (j = 0; j < 9; j++) { - for (d = 8; d < 80; d += 2) { - if (quant == 0) { /* 16bit quantization */ - of = sys->audio_shuffle[i][j] + (d - 8)/2 * sys->audio_stride; - if (of*2 >= size) - continue; - -#ifdef WORDS_BIGENDIAN - pcm[of*2] = frame[d]; - pcm[of*2+1] = frame[d+1]; -#else - pcm[of*2] = frame[d+1]; - pcm[of*2+1] = frame[d]; -#endif - if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00) - pcm[of*2+1] = 0; - } else { /* 12bit quantization */ - lc = ((uint16_t)frame[d] << 4) | - ((uint16_t)frame[d+2] >> 4); - rc = ((uint16_t)frame[d+1] << 4) | - ((uint16_t)frame[d+2] & 0x0f); - lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc)); - rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc)); - - of = sys->audio_shuffle[i%half_ch][j] + (d - 8)/3 * sys->audio_stride; - if (of*2 >= size) - continue; - -#ifdef WORDS_BIGENDIAN - pcm[of*2] = lc >> 8; - pcm[of*2+1] = lc & 0xff; -#else - pcm[of*2] = lc & 0xff; - pcm[of*2+1] = lc >> 8; -#endif - of = sys->audio_shuffle[i%half_ch+half_ch][j] + - (d - 8)/3 * sys->audio_stride; -#ifdef WORDS_BIGENDIAN - pcm[of*2] = rc >> 8; - pcm[of*2+1] = rc & 0xff; -#else - pcm[of*2] = rc & 0xff; - pcm[of*2+1] = rc >> 8; -#endif - ++d; - } - } - - frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ - } - } - - return size; -} - -static void dvaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - dvaudio_decoder_t *this = (dvaudio_decoder_t *) this_gen; - int bytes_consumed; - int decode_buffer_size; - int offset; - int out; - audio_buffer_t *audio_buffer; - int bytes_to_send; - - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - this->buf = xine_xmalloc(AUDIOBUFSIZE); - this->bufsize = AUDIOBUFSIZE; - this->size = 0; - this->decode_buffer = xine_xmalloc(MAXFRAMESIZE); - - this->audio_sample_rate = buf->decoder_info[1]; - this->audio_bits = buf->decoder_info[2]; - this->audio_channels = buf->decoder_info[3]; - - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DV Audio"); - - this->decoder_ok = 1; - - return; - } - - if (this->decoder_ok && !(buf->decoder_flags & (BUF_FLAG_HEADER|BUF_FLAG_SPECIAL))) { - - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, this->audio_bits, this->audio_sample_rate, - _x_ao_channels2mode(this->audio_channels)); - } - - /* if the audio still isn't open, bail */ - if (!this->output_open) - return; - - if( this->size + buf->size > this->bufsize ) { - this->bufsize = this->size + 2 * buf->size; - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("dvaudio: increasing buffer to %d to avoid overflow.\n"), - this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ - - offset = 0; - while (this->size>0) { - decode_buffer_size = dv_extract_audio(&this->buf[offset], this->decode_buffer, NULL); - - if (decode_buffer_size > -1) - bytes_consumed = dv_frame_profile(&this->buf[offset])->frame_size; - else - bytes_consumed = decode_buffer_size; - - /* dispatch the decoded audio */ - out = 0; - while (out < decode_buffer_size) { - audio_buffer = - this->stream->audio_out->get_buffer (this->stream->audio_out); - if (audio_buffer->mem_size == 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "dvaudio: Help! Allocated audio buffer with nothing in it!\n"); - return; - } - - if ((decode_buffer_size - out) > audio_buffer->mem_size) - bytes_to_send = audio_buffer->mem_size; - else - bytes_to_send = decode_buffer_size - out; - - /* fill up this buffer */ - xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out], - bytes_to_send); - /* byte count / 2 (bytes / sample) / channels */ - audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels; - - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, - audio_buffer, this->stream); - - out += bytes_to_send; - } - - this->size -= bytes_consumed; - offset += bytes_consumed; - } - - /* reset internal accumulation buffer */ - this->size = 0; - } - } -} - -static void dvaudio_reset (audio_decoder_t *this_gen) { - dvaudio_decoder_t *this = (dvaudio_decoder_t *) this_gen; - - this->size = 0; -} - -static void dvaudio_discontinuity (audio_decoder_t *this_gen) { -} - -static void dvaudio_dispose (audio_decoder_t *this_gen) { - - dvaudio_decoder_t *this = (dvaudio_decoder_t *) this_gen; - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - free(this->buf); - free(this->decode_buffer); - - free (this_gen); -} - -static audio_decoder_t *dvaudio_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - dvaudio_decoder_t *this ; - - this = (dvaudio_decoder_t *) xine_xmalloc (sizeof (dvaudio_decoder_t)); - - this->audio_decoder.decode_data = dvaudio_decode_data; - this->audio_decoder.reset = dvaudio_reset; - this->audio_decoder.discontinuity = dvaudio_discontinuity; - this->audio_decoder.dispose = dvaudio_dispose; - - this->output_open = 0; - this->audio_channels = 0; - this->stream = stream; - this->buf = NULL; - this->size = 0; - this->decoder_ok = 0; - - return &this->audio_decoder; -} - -static void *init_dvaudio_plugin (xine_t *xine, void *data) { - - dvaudio_class_t *this ; - - this = (dvaudio_class_t *) xine_xmalloc (sizeof (dvaudio_class_t)); - - this->decoder_class.open_plugin = dvaudio_open_plugin; - this->decoder_class.identifier = "dv audio"; - this->decoder_class.description = N_("dv audio decoder plugin"); - this->decoder_class.dispose = default_audio_decoder_class_dispose; - - return this; -} - -static uint32_t supported_audio_types[] = { - BUF_AUDIO_DV, - 0 -}; - -static const decoder_info_t dec_info_dvaudio = { - supported_audio_types, /* supported types */ - 5 /* priority */ -}; - -/* - * exported plugin catalog entry - */ - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 16, "dvaudio", XINE_VERSION_CODE, &dec_info_dvaudio, init_dvaudio_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libffmpeg/ff_mpeg_parser.c b/src/libffmpeg/ff_mpeg_parser.c deleted file mode 100644 index 70901d93b..000000000 --- a/src/libffmpeg/ff_mpeg_parser.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2001-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) - * based on libmpeg2 decoder. - */ -#define LOG_MODULE "mpeg_parser" -#define LOG_VERBOSE -/* -#define LOG -*/ -#include "ff_mpeg_parser.h" - -/* mpeg frame rate table from lavc */ -static const int frame_rate_tab[][2] = { - { 0, 0}, - {24000, 1001}, - { 24, 1}, - { 25, 1}, - {30000, 1001}, - { 30, 1}, - { 50, 1}, - {60000, 1001}, - { 60, 1}, - /* Xing's 15fps: (9) */ - { 15, 1}, - /* libmpeg3's "Unofficial economy rates": (10-13) */ - { 5, 1}, - { 10, 1}, - { 12, 1}, - { 15, 1}, - { 0, 0}, -}; - -void mpeg_parser_init (mpeg_parser_t *parser) -{ - parser->chunk_buffer = xine_xmalloc(BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - mpeg_parser_reset(parser); -} - -void mpeg_parser_dispose (mpeg_parser_t *parser) -{ - if ( parser == NULL ) return; - - free(parser->chunk_buffer); -} - -void mpeg_parser_reset (mpeg_parser_t *parser) -{ - parser->shift = 0xffffff00; - parser->is_sequence_needed = 1; - parser->in_slice = 0; - parser->chunk_ptr = parser->chunk_buffer; - parser->chunk_start = parser->chunk_buffer; - parser->buffer_size = 0; - parser->code = 0xb4; - parser->picture_coding_type = 0; - parser->width = 0; - parser->height = 0; - parser->rate_code = 0; - parser->aspect_ratio_info = 0; - parser->frame_duration = 0; - parser->is_mpeg1 = 0; - parser->has_sequence = 0; - parser->frame_aspect_ratio = 0.0; -} - -static void parse_header_picture (mpeg_parser_t *parser, uint8_t * buffer) -{ - parser->picture_coding_type = (buffer [1] >> 3) & 7; -} - -static double get_aspect_ratio(mpeg_parser_t *parser) -{ - double ratio; - double mpeg1_pel_ratio[16] = {1.0 /* forbidden */, - 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, - 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ }; - - if( !parser->is_mpeg1 ) { - /* these hardcoded values are defined on mpeg2 standard for - * aspect ratio. other values are reserved or forbidden. */ - switch (parser->aspect_ratio_info) { - case 2: - ratio = 4.0 / 3.0; - break; - case 3: - ratio = 16.0 / 9.0; - break; - case 4: - ratio = 2.11 / 1.0; - break; - case 1: - default: - ratio = (double)parser->width / (double)parser->height; - break; - } - } else { - /* mpeg1 constants refer to pixel aspect ratio */ - ratio = (double)parser->width / (double)parser->height; - ratio /= mpeg1_pel_ratio[parser->aspect_ratio_info]; - } - - return ratio; -} - -static int parse_chunk (mpeg_parser_t *parser, int code, uint8_t *buffer, int len) -{ - int is_frame_done; - int next_code = parser->code; - - /* wait for sequence_header_code */ - if (parser->is_sequence_needed) { - if (code != 0xb3) { - lprintf("waiting for sequence header\n"); - parser->chunk_ptr = parser->chunk_buffer; - return 0; - } - } - - is_frame_done = parser->in_slice && ((!next_code) || (next_code == 0xb7)); - - if (is_frame_done) - parser->in_slice = 0; - - switch (code) { - case 0x00: /* picture_start_code */ - - parse_header_picture (parser, buffer); - - parser->in_slice = 1; - - switch (parser->picture_coding_type) { - case B_TYPE: - lprintf ("B-Frame\n"); - break; - - case P_TYPE: - lprintf ("P-Frame\n"); - break; - - case I_TYPE: - lprintf ("I-Frame\n"); - break; - } - break; - - case 0xb2: /* user data code */ - /* process_userdata(mpeg2dec, buffer); */ - break; - - case 0xb3: /* sequence_header_code */ - { - int value; - uint16_t width, height; - - if (parser->is_sequence_needed) { - parser->is_sequence_needed = 0; - } - - if ((buffer[6] & 0x20) != 0x20) { - lprintf("Invalid sequence: missing marker_bit\n"); - parser->has_sequence = 0; - break; /* missing marker_bit */ - } - - value = (buffer[0] << 16) | - (buffer[1] << 8) | - buffer[2]; - width = ((value >> 12) + 15) & ~15; - height = ((value & 0xfff) + 15) & ~15; - - if ((width > 1920) || (height > 1152)) { - lprintf("Invalid sequence: width=%d, height=%d\n", width, height); - parser->has_sequence = 0; - break; /* size restrictions for MP@HL */ - } - - parser->width = width; - parser->height = height; - parser->rate_code = buffer[3] & 15; - parser->aspect_ratio_info = buffer[3] >> 4; - - if (parser->rate_code < (sizeof(frame_rate_tab)/sizeof(*frame_rate_tab))) { - parser->frame_duration = 90000; - parser->frame_duration *= frame_rate_tab[parser->rate_code][1]; - parser->frame_duration /= frame_rate_tab[parser->rate_code][0]; - } else { - printf ("invalid/unknown frame rate code : %d \n", - parser->rate_code); - parser->frame_duration = 0; - } - - parser->has_sequence = 1; - parser->is_mpeg1 = 1; - } - break; - - case 0xb5: /* extension_start_code */ - switch (buffer[0] & 0xf0) { - case 0x10: /* sequence extension */ - parser->is_mpeg1 = 0; - } - - default: - if (code >= 0xb9) - lprintf ("stream not demultiplexed ?\n"); - - if (code >= 0xb0) - break; - } - return is_frame_done; -} - -static inline uint8_t *copy_chunk (mpeg_parser_t *parser, - uint8_t *current, uint8_t *end) -{ - uint32_t shift; - uint8_t *chunk_ptr; - uint8_t *limit; - uint8_t byte; - - shift = parser->shift; - chunk_ptr = parser->chunk_ptr; - - limit = current + (parser->chunk_buffer + BUFFER_SIZE - chunk_ptr); - if (limit > end) - limit = end; - - while (1) { - - byte = *current++; - *chunk_ptr++ = byte; - if (shift != 0x00000100) { - shift = (shift | byte) << 8; - if (current < limit) - continue; - if (current == end) { - parser->chunk_ptr = chunk_ptr; - parser->shift = shift; - lprintf("Need more bytes\n"); - return NULL; - } else { - /* we filled the chunk buffer without finding a start code */ - lprintf("Buffer full\n"); - parser->code = 0xb4; /* sequence_error_code */ - parser->chunk_ptr = parser->chunk_buffer; - return current; - } - } - lprintf("New chunk: 0x%2X\n", byte); - parser->chunk_ptr = chunk_ptr; - parser->shift = 0xffffff00; - parser->code = byte; - return current; - } -} - - -uint8_t *mpeg_parser_decode_data (mpeg_parser_t *parser, - uint8_t *current, uint8_t *end, - int *flush) -{ - int ret; - uint8_t code; - - ret = 0; - *flush = 0; - - while (current != end) { - if (parser->chunk_ptr == parser->chunk_buffer) { - /* write the beginning of the chunk */ - parser->chunk_buffer[0] = 0x00; - parser->chunk_buffer[1] = 0x00; - parser->chunk_buffer[2] = 0x01; - parser->chunk_buffer[3] = parser->code; - parser->chunk_ptr += 4; - parser->chunk_start = parser->chunk_ptr; - parser->has_sequence = 0; - } - - code = parser->code; - - current = copy_chunk (parser, current, end); - if (current == NULL) - return NULL; - ret = parse_chunk (parser, code, parser->chunk_start, - parser->chunk_ptr - parser->chunk_start - 4); - parser->chunk_start = parser->chunk_ptr; - if (ret == 1) { - if (parser->has_sequence) { - parser->frame_aspect_ratio = get_aspect_ratio(parser); - } - parser->buffer_size = parser->chunk_ptr - parser->chunk_buffer - 4; - parser->chunk_ptr = parser->chunk_buffer; - - if (parser->code == 0xb7) /* sequence end, maybe a still menu */ - *flush = 1; - - return current; - } - } - - return NULL; -} diff --git a/src/libffmpeg/ff_mpeg_parser.h b/src/libffmpeg/ff_mpeg_parser.h deleted file mode 100644 index 504e746f9..000000000 --- a/src/libffmpeg/ff_mpeg_parser.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2001-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) - * based on libmpeg2 decoder. - */ -#ifndef HAVE_MPEG_PARSER_H -#define HAVE_MPEG_PARSER_H - -#include -#include "ffmpeg_decoder.h" - -#define BUFFER_SIZE (1194 * 1024) /* libmpeg2's buffer size */ - -/* picture coding type (mpeg2 header) */ -#define I_TYPE 1 -#define P_TYPE 2 -#define B_TYPE 3 -#define D_TYPE 4 - -typedef struct mpeg_parser_s { - uint8_t *chunk_buffer; - uint8_t *chunk_ptr; - uint8_t *chunk_start; - uint32_t shift; - int buffer_size; - uint8_t code; - uint8_t picture_coding_type; - - uint8_t is_sequence_needed:1; - uint8_t is_mpeg1:1; /* public */ - uint8_t has_sequence:1; /* public */ - uint8_t in_slice:1; - - uint8_t rate_code:4; - - int aspect_ratio_info; - - /* public properties */ - uint16_t width; - uint16_t height; - int frame_duration; - double frame_aspect_ratio; - -} mpeg_parser_t; - -/* parser initialization */ -void mpeg_parser_init (mpeg_parser_t *parser); - -/* parser disposal */ -void mpeg_parser_dispose (mpeg_parser_t *parser); - -/* read a frame - * return a pointer to the first byte of the next frame - * or NULL if more bytes are needed - * *flush is set to 1 if the decoder must be flushed (needed for still menus) - */ -uint8_t *mpeg_parser_decode_data (mpeg_parser_t *parser, - uint8_t *current, uint8_t *end, - int *flush); - -/* reset the parser */ -void mpeg_parser_reset (mpeg_parser_t *parser); - -#endif /* HAVE_MPEG_PARSER_H */ diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c deleted file mode 100644 index 4e5e1ebdf..000000000 --- a/src/libffmpeg/ff_video_decoder.c +++ /dev/null @@ -1,1816 +0,0 @@ -/* - * Copyright (C) 2001-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine video decoder plugin using ffmpeg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -# ifndef HAVE_FFMPEG -# include "ffmpeg_config.h" -# endif -#endif - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "ffmpeg_video_dec" -#define LOG_VERBOSE -/* -#define LOG -*/ -#include -#include "bswap.h" -#include -#include -#include "ffmpeg_decoder.h" -#include "ff_mpeg_parser.h" - -#include - -#define VIDEOBUFSIZE (128*1024) -#define SLICE_BUFFER_SIZE (1194*1024) - -#define SLICE_OFFSET_SIZE 128 - -#define ENABLE_DIRECT_RENDERING - -typedef struct ff_video_decoder_s ff_video_decoder_t; - -typedef struct ff_video_class_s { - video_decoder_class_t decoder_class; - - int pp_quality; - int thread_count; - - xine_t *xine; -} ff_video_class_t; - -struct ff_video_decoder_s { - video_decoder_t video_decoder; - - ff_video_class_t *class; - - xine_stream_t *stream; - int64_t pts; - int video_step; - - uint8_t decoder_ok:1; - uint8_t decoder_init_mode:1; - uint8_t is_mpeg12:1; - uint8_t pp_available:1; - uint8_t yuv_init:1; - uint8_t is_direct_rendering_disabled:1; - uint8_t cs_convert_init:1; - uint8_t assume_bad_field_picture:1; - - xine_bmiheader bih; - unsigned char *buf; - int bufsize; - int size; - int skipframes; - - int slice_offset_size; - - AVFrame *av_frame; - AVCodecContext *context; - AVCodec *codec; - - int pp_quality; - int pp_flags; - pp_context_t *pp_context; - pp_mode_t *pp_mode; - - /* mpeg-es parsing */ - mpeg_parser_t *mpeg_parser; - - double aspect_ratio; - int aspect_ratio_prio; - int frame_flags; - int crop_right, crop_bottom; - - int output_format; - - xine_list_t *dr1_frames; - - yuv_planes_t yuv; - - AVPaletteControl palette_control; -}; - - -static void set_stream_info(ff_video_decoder_t *this) { - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->aspect_ratio * 10000); -} - -#ifdef ENABLE_DIRECT_RENDERING -/* called from ffmpeg to do direct rendering method 1 */ -static int get_buffer(AVCodecContext *context, AVFrame *av_frame){ - ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; - vo_frame_t *img; - int width = context->width; - int height = context->height; - - if (!this->bih.biWidth || !this->bih.biHeight) { - this->bih.biWidth = width; - this->bih.biHeight = height; - - if (this->aspect_ratio_prio == 0) { - this->aspect_ratio = (double)width / (double)height; - this->aspect_ratio_prio = 1; - lprintf("default aspect ratio: %f\n", this->aspect_ratio); - set_stream_info(this); - } - } - - avcodec_align_dimensions(context, &width, &height); - - if( this->context->pix_fmt != PIX_FMT_YUV420P ) { - if (!this->is_direct_rendering_disabled) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n")); - this->is_direct_rendering_disabled = 1; - } - - /* FIXME: why should i have to do that ? */ - av_frame->data[0]= NULL; - av_frame->data[1]= NULL; - av_frame->data[2]= NULL; - return avcodec_default_get_buffer(context, av_frame); - } - - if((width != this->bih.biWidth) || (height != this->bih.biHeight)) { - if(this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_CROP) { - this->crop_right = width - this->bih.biWidth; - this->crop_bottom = height - this->bih.biHeight; - } else { - if (!this->is_direct_rendering_disabled) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n")); - this->is_direct_rendering_disabled = 1; - } - /* FIXME: why should i have to do that ? */ - av_frame->data[0]= NULL; - av_frame->data[1]= NULL; - av_frame->data[2]= NULL; - return avcodec_default_get_buffer(context, av_frame); - } - } - - img = this->stream->video_out->get_frame (this->stream->video_out, - width, - height, - this->aspect_ratio, - this->output_format, - VO_BOTH_FIELDS|this->frame_flags); - - av_frame->opaque = img; - - av_frame->data[0]= img->base[0]; - av_frame->data[1]= img->base[1]; - av_frame->data[2]= img->base[2]; - - av_frame->linesize[0] = img->pitches[0]; - av_frame->linesize[1] = img->pitches[1]; - av_frame->linesize[2] = img->pitches[2]; - - /* We should really keep track of the ages of xine frames (see - * avcodec_default_get_buffer in libavcodec/utils.c) - * For the moment tell ffmpeg that every frame is new (age = bignumber) */ - av_frame->age = 256*256*256*64; - - av_frame->type= FF_BUFFER_TYPE_USER; - - xine_list_push_back(this->dr1_frames, av_frame); - - return 0; -} - -static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){ - ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; - - if (av_frame->type == FF_BUFFER_TYPE_USER) { - if ( av_frame->opaque ) { - vo_frame_t *img = (vo_frame_t *)av_frame->opaque; - - img->free(img); - } - - xine_list_iterator_t it; - - it = xine_list_find(this->dr1_frames, av_frame); - assert(it); - if( it != NULL ) - xine_list_remove(this->dr1_frames, it); - } else { - avcodec_default_release_buffer(context, av_frame); - } - - av_frame->opaque = NULL; - av_frame->data[0]= NULL; - av_frame->data[1]= NULL; - av_frame->data[2]= NULL; -} -#endif - -static const ff_codec_t ff_video_lookup[] = { - {BUF_VIDEO_MSMPEG4_V1, CODEC_ID_MSMPEG4V1, "Microsoft MPEG-4 v1 (ffmpeg)"}, - {BUF_VIDEO_MSMPEG4_V2, CODEC_ID_MSMPEG4V2, "Microsoft MPEG-4 v2 (ffmpeg)"}, - {BUF_VIDEO_MSMPEG4_V3, CODEC_ID_MSMPEG4V3, "Microsoft MPEG-4 v3 (ffmpeg)"}, - {BUF_VIDEO_WMV7, CODEC_ID_WMV1, "MS Windows Media Video 7 (ffmpeg)"}, - {BUF_VIDEO_WMV8, CODEC_ID_WMV2, "MS Windows Media Video 8 (ffmpeg)"}, - {BUF_VIDEO_WMV9, CODEC_ID_WMV3, "MS Windows Media Video 9 (ffmpeg)"}, - {BUF_VIDEO_VC1, CODEC_ID_VC1, "MS Windows Media Video VC-1 (ffmpeg)"}, - {BUF_VIDEO_MPEG4, CODEC_ID_MPEG4, "ISO MPEG-4 (ffmpeg)"}, - {BUF_VIDEO_XVID, CODEC_ID_MPEG4, "ISO MPEG-4 (XviD, ffmpeg)"}, - {BUF_VIDEO_DIVX5, CODEC_ID_MPEG4, "ISO MPEG-4 (DivX5, ffmpeg)"}, - {BUF_VIDEO_3IVX, CODEC_ID_MPEG4, "ISO MPEG-4 (3ivx, ffmpeg)"}, - {BUF_VIDEO_JPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"}, - {BUF_VIDEO_MJPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"}, - {BUF_VIDEO_MJPEG_B, CODEC_ID_MJPEGB, "Motion JPEG B (ffmpeg)"}, - {BUF_VIDEO_I263, CODEC_ID_H263I, "ITU H.263 (ffmpeg)"}, - {BUF_VIDEO_H263, CODEC_ID_H263, "H.263 (ffmpeg)"}, - {BUF_VIDEO_RV10, CODEC_ID_RV10, "Real Video 1.0 (ffmpeg)"}, - {BUF_VIDEO_RV20, CODEC_ID_RV20, "Real Video 2.0 (ffmpeg)"}, - {BUF_VIDEO_IV31, CODEC_ID_INDEO3, "Indeo Video 3.1 (ffmpeg)"}, - {BUF_VIDEO_IV32, CODEC_ID_INDEO3, "Indeo Video 3.2 (ffmpeg)"}, - {BUF_VIDEO_SORENSON_V1, CODEC_ID_SVQ1, "Sorenson Video 1 (ffmpeg)"}, - {BUF_VIDEO_SORENSON_V3, CODEC_ID_SVQ3, "Sorenson Video 3 (ffmpeg)"}, - {BUF_VIDEO_DV, CODEC_ID_DVVIDEO, "DV (ffmpeg)"}, - {BUF_VIDEO_HUFFYUV, CODEC_ID_HUFFYUV, "HuffYUV (ffmpeg)"}, - {BUF_VIDEO_VP31, CODEC_ID_VP3, "On2 VP3.1 (ffmpeg)"}, - {BUF_VIDEO_VP5, CODEC_ID_VP5, "On2 VP5 (ffmpeg)"}, - {BUF_VIDEO_VP6, CODEC_ID_VP6, "On2 VP6 (ffmpeg)"}, - {BUF_VIDEO_VP6F, CODEC_ID_VP6F, "On2 VP6 (ffmpeg)"}, - {BUF_VIDEO_4XM, CODEC_ID_4XM, "4X Video (ffmpeg)"}, - {BUF_VIDEO_CINEPAK, CODEC_ID_CINEPAK, "Cinepak (ffmpeg)"}, - {BUF_VIDEO_MSVC, CODEC_ID_MSVIDEO1, "Microsoft Video 1 (ffmpeg)"}, - {BUF_VIDEO_MSRLE, CODEC_ID_MSRLE, "Microsoft RLE (ffmpeg)"}, - {BUF_VIDEO_RPZA, CODEC_ID_RPZA, "Apple Quicktime Video/RPZA (ffmpeg)"}, - {BUF_VIDEO_CYUV, CODEC_ID_CYUV, "Creative YUV (ffmpeg)"}, - {BUF_VIDEO_ROQ, CODEC_ID_ROQ, "Id Software RoQ (ffmpeg)"}, - {BUF_VIDEO_IDCIN, CODEC_ID_IDCIN, "Id Software CIN (ffmpeg)"}, - {BUF_VIDEO_WC3, CODEC_ID_XAN_WC3, "Xan (ffmpeg)"}, - {BUF_VIDEO_VQA, CODEC_ID_WS_VQA, "Westwood Studios VQA (ffmpeg)"}, - {BUF_VIDEO_INTERPLAY, CODEC_ID_INTERPLAY_VIDEO, "Interplay MVE (ffmpeg)"}, - {BUF_VIDEO_FLI, CODEC_ID_FLIC, "FLIC Video (ffmpeg)"}, - {BUF_VIDEO_8BPS, CODEC_ID_8BPS, "Planar RGB (ffmpeg)"}, - {BUF_VIDEO_SMC, CODEC_ID_SMC, "Apple Quicktime Graphics/SMC (ffmpeg)"}, - {BUF_VIDEO_DUCKTM1, CODEC_ID_TRUEMOTION1,"Duck TrueMotion v1 (ffmpeg)"}, - {BUF_VIDEO_DUCKTM2, CODEC_ID_TRUEMOTION2,"Duck TrueMotion v2 (ffmpeg)"}, - {BUF_VIDEO_VMD, CODEC_ID_VMDVIDEO, "Sierra VMD Video (ffmpeg)"}, - {BUF_VIDEO_ZLIB, CODEC_ID_ZLIB, "ZLIB Video (ffmpeg)"}, - {BUF_VIDEO_MSZH, CODEC_ID_MSZH, "MSZH Video (ffmpeg)"}, - {BUF_VIDEO_ASV1, CODEC_ID_ASV1, "ASV v1 Video (ffmpeg)"}, - {BUF_VIDEO_ASV2, CODEC_ID_ASV2, "ASV v2 Video (ffmpeg)"}, - {BUF_VIDEO_ATIVCR1, CODEC_ID_VCR1, "ATI VCR-1 (ffmpeg)"}, - {BUF_VIDEO_FLV1, CODEC_ID_FLV1, "Flash Video (ffmpeg)"}, - {BUF_VIDEO_QTRLE, CODEC_ID_QTRLE, "Apple Quicktime Animation/RLE (ffmpeg)"}, - {BUF_VIDEO_H264, CODEC_ID_H264, "H.264/AVC (ffmpeg)"}, - {BUF_VIDEO_H261, CODEC_ID_H261, "H.261 (ffmpeg)"}, - {BUF_VIDEO_AASC, CODEC_ID_AASC, "Autodesk Video (ffmpeg)"}, - {BUF_VIDEO_LOCO, CODEC_ID_LOCO, "LOCO (ffmpeg)"}, - {BUF_VIDEO_QDRW, CODEC_ID_QDRAW, "QuickDraw (ffmpeg)"}, - {BUF_VIDEO_QPEG, CODEC_ID_QPEG, "Q-Team QPEG (ffmpeg)"}, - {BUF_VIDEO_TSCC, CODEC_ID_TSCC, "TechSmith Video (ffmpeg)"}, - {BUF_VIDEO_ULTI, CODEC_ID_ULTI, "IBM UltiMotion (ffmpeg)"}, - {BUF_VIDEO_WNV1, CODEC_ID_WNV1, "Winnow Video (ffmpeg)"}, - {BUF_VIDEO_XL, CODEC_ID_VIXL, "Miro/Pinnacle VideoXL (ffmpeg)"}, - {BUF_VIDEO_RT21, CODEC_ID_INDEO2, "Indeo/RealTime 2 (ffmpeg)"}, - {BUF_VIDEO_FPS1, CODEC_ID_FRAPS, "Fraps (ffmpeg)"}, - {BUF_VIDEO_MPEG, CODEC_ID_MPEG1VIDEO, "MPEG 1/2 (ffmpeg)"}, - {BUF_VIDEO_CSCD, CODEC_ID_CSCD, "CamStudio (ffmpeg)"}, - {BUF_VIDEO_AVS, CODEC_ID_AVS, "AVS (ffmpeg)"}, - {BUF_VIDEO_ALGMM, CODEC_ID_MMVIDEO, "American Laser Games MM (ffmpeg)"}, - {BUF_VIDEO_ZMBV, CODEC_ID_ZMBV, "Zip Motion Blocks Video (ffmpeg)"}, - {BUF_VIDEO_SMACKER, CODEC_ID_SMACKVIDEO, "Smacker (ffmpeg)"}, - {BUF_VIDEO_NUV, CODEC_ID_NUV, "NuppelVideo (ffmpeg)"}, - {BUF_VIDEO_KMVC, CODEC_ID_KMVC, "Karl Morton's Video Codec (ffmpeg)"}, - {BUF_VIDEO_FLASHSV, CODEC_ID_FLASHSV, "Flash Screen Video (ffmpeg)"}, - {BUF_VIDEO_CAVS, CODEC_ID_CAVS, "Chinese AVS (ffmpeg)"}, - {BUF_VIDEO_THEORA_RAW, CODEC_ID_THEORA, "Theora (ffmpeg)"}, -}; - - -static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) { - size_t i; - - /* find the decoder */ - this->codec = NULL; - - for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++) - if(ff_video_lookup[i].type == codec_type) { - pthread_mutex_lock(&ffmpeg_lock); - this->codec = avcodec_find_decoder(ff_video_lookup[i].id); - pthread_mutex_unlock(&ffmpeg_lock); - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, - ff_video_lookup[i].name); - break; - } - - if (!this->codec) { - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"), - codec_type); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - } - - lprintf("lavc decoder found\n"); - - /* force (width % 8 == 0), otherwise there will be - * display problems with Xv. - */ - this->bih.biWidth = (this->bih.biWidth + 1) & (~1); - - this->context->width = this->bih.biWidth; - this->context->height = this->bih.biHeight; - this->context->stream_codec_tag = this->context->codec_tag = - _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC); - - - /* Some codecs (eg rv10) copy flags in init so it's necessary to set - * this flag here in case we are going to use direct rendering */ - if(this->codec->capabilities & CODEC_CAP_DR1) { - this->context->flags |= CODEC_FLAG_EMU_EDGE; - } - - pthread_mutex_lock(&ffmpeg_lock); - if (avcodec_open (this->context, this->codec) < 0) { - pthread_mutex_unlock(&ffmpeg_lock); - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: couldn't open decoder\n")); - free(this->context); - this->context = NULL; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - } - - if (this->class->thread_count > 1) { - avcodec_thread_init(this->context, this->class->thread_count); - this->context->thread_count = this->class->thread_count; - } - - pthread_mutex_unlock(&ffmpeg_lock); - - lprintf("lavc decoder opened\n"); - - this->decoder_ok = 1; - - if ((codec_type != BUF_VIDEO_MPEG) && - (codec_type != BUF_VIDEO_DV)) { - - if (!this->bih.biWidth || !this->bih.biHeight) { - this->bih.biWidth = this->context->width; - this->bih.biHeight = this->context->height; - } - - - set_stream_info(this); - } - - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - this->skipframes = 0; - - /* enable direct rendering by default */ - this->output_format = XINE_IMGFMT_YV12; -#ifdef ENABLE_DIRECT_RENDERING - if( this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264 ) { - this->context->get_buffer = get_buffer; - this->context->release_buffer = release_buffer; - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: direct rendering enabled\n")); - } -#endif - - /* flag for interlaced streams */ - this->frame_flags = 0; - /* FIXME: which codecs can be interlaced? - FIXME: check interlaced DCT and other codec specific info. */ - switch( codec_type ) { - case BUF_VIDEO_DV: - this->frame_flags |= VO_INTERLACED_FLAG; - break; - case BUF_VIDEO_MPEG: - this->frame_flags |= VO_INTERLACED_FLAG; - break; - case BUF_VIDEO_MJPEG: - this->frame_flags |= VO_INTERLACED_FLAG; - break; - case BUF_VIDEO_HUFFYUV: - this->frame_flags |= VO_INTERLACED_FLAG; - break; - case BUF_VIDEO_H264: - this->frame_flags |= VO_INTERLACED_FLAG; - break; - } - -} - -static void thread_count_cb(void *user_data, xine_cfg_entry_t *entry) { - ff_video_class_t *class = (ff_video_class_t *) user_data; - - class->thread_count = entry->num_value; -} - -static void pp_quality_cb(void *user_data, xine_cfg_entry_t *entry) { - ff_video_class_t *class = (ff_video_class_t *) user_data; - - class->pp_quality = entry->num_value; -} - -static void pp_change_quality (ff_video_decoder_t *this) { - this->pp_quality = this->class->pp_quality; - - if(this->pp_available && this->pp_quality) { - if(!this->pp_context && this->context) - this->pp_context = pp_get_context(this->context->width, this->context->height, - this->pp_flags); - if(this->pp_mode) - pp_free_mode(this->pp_mode); - - this->pp_mode = pp_get_mode_by_name_and_quality("hb:a,vb:a,dr:a", - this->pp_quality); - } else { - if(this->pp_mode) { - pp_free_mode(this->pp_mode); - this->pp_mode = NULL; - } - - if(this->pp_context) { - pp_free_context(this->pp_context); - this->pp_context = NULL; - } - } -} - -static void init_postprocess (ff_video_decoder_t *this) { - uint32_t cpu_caps; - - /* Allow post processing on mpeg-4 (based) codecs */ - switch(this->codec->id) { - case CODEC_ID_MPEG4: - case CODEC_ID_MSMPEG4V1: - case CODEC_ID_MSMPEG4V2: - case CODEC_ID_MSMPEG4V3: - case CODEC_ID_WMV1: - case CODEC_ID_WMV2: - this->pp_available = 1; - break; - default: - this->pp_available = 0; - break; - } - - /* Detect what cpu accel we have */ - cpu_caps = xine_mm_accel(); - this->pp_flags = PP_FORMAT_420; - - if(cpu_caps & MM_ACCEL_X86_MMX) - this->pp_flags |= PP_CPU_CAPS_MMX; - - if(cpu_caps & MM_ACCEL_X86_MMXEXT) - this->pp_flags |= PP_CPU_CAPS_MMX2; - - if(cpu_caps & MM_ACCEL_X86_3DNOW) - this->pp_flags |= PP_CPU_CAPS_3DNOW; - - /* Set level */ - pp_change_quality(this); -} - -static int ff_handle_mpeg_sequence(ff_video_decoder_t *this, mpeg_parser_t *parser) { - - /* - * init codec - */ - if (this->decoder_init_mode) { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, - "mpeg-1 (ffmpeg)"); - - init_video_codec (this, BUF_VIDEO_MPEG); - this->decoder_init_mode = 0; - } - - /* frame format change */ - if ((parser->width != this->bih.biWidth) || - (parser->height != this->bih.biHeight) || - (parser->frame_aspect_ratio != this->aspect_ratio)) { - xine_event_t event; - xine_format_change_data_t data; - - this->bih.biWidth = parser->width; - this->bih.biHeight = parser->height; - this->aspect_ratio = parser->frame_aspect_ratio; - this->aspect_ratio_prio = 2; - lprintf("mpeg seq aspect ratio: %f\n", this->aspect_ratio); - set_stream_info(this); - - event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; - event.stream = this->stream; - event.data = &data; - event.data_length = sizeof(data); - data.width = this->bih.biWidth; - data.height = this->bih.biHeight; - data.aspect = this->aspect_ratio; - data.pan_scan = 0; - xine_event_send(this->stream, &event); - } - this->video_step = this->mpeg_parser->frame_duration; - - return 1; -} - -static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { - int y; - uint8_t *dy, *du, *dv, *sy, *su, *sv; - - dy = img->base[0]; - du = img->base[1]; - dv = img->base[2]; - sy = this->av_frame->data[0]; - su = this->av_frame->data[1]; - sv = this->av_frame->data[2]; - - if (this->context->pix_fmt == PIX_FMT_YUV410P) { - - yuv9_to_yv12( - /* Y */ - this->av_frame->data[0], - this->av_frame->linesize[0], - img->base[0], - img->pitches[0], - /* U */ - this->av_frame->data[1], - this->av_frame->linesize[1], - img->base[1], - img->pitches[1], - /* V */ - this->av_frame->data[2], - this->av_frame->linesize[2], - img->base[2], - img->pitches[2], - /* width x height */ - img->width, - img->height); - - } else if (this->context->pix_fmt == PIX_FMT_YUV411P) { - - yuv411_to_yv12( - /* Y */ - this->av_frame->data[0], - this->av_frame->linesize[0], - img->base[0], - img->pitches[0], - /* U */ - this->av_frame->data[1], - this->av_frame->linesize[1], - img->base[1], - img->pitches[1], - /* V */ - this->av_frame->data[2], - this->av_frame->linesize[2], - img->base[2], - img->pitches[2], - /* width x height */ - img->width, - img->height); - - } else if (this->context->pix_fmt == PIX_FMT_RGBA32) { - - int x, plane_ptr = 0; - uint32_t *argb_pixels; - uint32_t argb; - - for(y = 0; y < img->height; y++) { - argb_pixels = (uint32_t *)sy; - for(x = 0; x < img->width; x++) { - uint8_t r, g, b; - - /* this is endian-safe as the ARGB pixels are stored in - * machine order */ - argb = *argb_pixels++; - r = (argb >> 16) & 0xFF; - g = (argb >> 8) & 0xFF; - b = (argb >> 0) & 0xFF; - - this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); - this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); - this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); - plane_ptr++; - } - sy += this->av_frame->linesize[0]; - } - - yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); - - } else if (this->context->pix_fmt == PIX_FMT_RGB565) { - - int x, plane_ptr = 0; - uint8_t *src; - uint16_t pixel16; - - for(y = 0; y < img->height; y++) { - src = sy; - for(x = 0; x < img->width; x++) { - uint8_t r, g, b; - - /* a 16-bit RGB565 pixel is supposed to be stored in native-endian - * byte order; the following should be endian-safe */ - pixel16 = *((uint16_t *)src); - src += 2; - b = (pixel16 << 3) & 0xFF; - g = (pixel16 >> 3) & 0xFF; - r = (pixel16 >> 8) & 0xFF; - - this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); - this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); - this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); - plane_ptr++; - } - sy += this->av_frame->linesize[0]; - } - - yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); - - } else if (this->context->pix_fmt == PIX_FMT_RGB555) { - - int x, plane_ptr = 0; - uint8_t *src; - uint16_t pixel16; - - for(y = 0; y < img->height; y++) { - src = sy; - for(x = 0; x < img->width; x++) { - uint8_t r, g, b; - - /* a 16-bit RGB555 pixel is supposed to be stored in native-endian - * byte order; the following should be endian-safe */ - pixel16 = *((uint16_t *)src); - src += 2; - b = (pixel16 << 3) & 0xFF; - g = (pixel16 >> 2) & 0xFF; - r = (pixel16 >> 7) & 0xFF; - - this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); - this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); - this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); - plane_ptr++; - } - sy += this->av_frame->linesize[0]; - } - - yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); - - } else if (this->context->pix_fmt == PIX_FMT_BGR24) { - - int x, plane_ptr = 0; - uint8_t *src; - - for(y = 0; y < img->height; y++) { - src = sy; - for(x = 0; x < img->width; x++) { - uint8_t r, g, b; - - b = *src++; - g = *src++; - r = *src++; - - this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); - this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); - this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); - plane_ptr++; - } - sy += this->av_frame->linesize[0]; - } - - yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); - - } else if (this->context->pix_fmt == PIX_FMT_RGB24) { - - int x, plane_ptr = 0; - uint8_t *src; - - for(y = 0; y < img->height; y++) { - src = sy; - for(x = 0; x < img->width; x++) { - uint8_t r, g, b; - - r = *src++; - g = *src++; - b = *src++; - - this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); - this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); - this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); - plane_ptr++; - } - sy += this->av_frame->linesize[0]; - } - - yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); - - } else if (this->context->pix_fmt == PIX_FMT_PAL8) { - - int x, plane_ptr = 0; - uint8_t *src; - uint8_t pixel; - uint32_t *palette32 = (uint32_t *)su; /* palette is in data[1] */ - uint32_t rgb_color; - uint8_t r, g, b; - uint8_t y_palette[256]; - uint8_t u_palette[256]; - uint8_t v_palette[256]; - - for (x = 0; x < 256; x++) { - rgb_color = palette32[x]; - b = rgb_color & 0xFF; - rgb_color >>= 8; - g = rgb_color & 0xFF; - rgb_color >>= 8; - r = rgb_color & 0xFF; - y_palette[x] = COMPUTE_Y(r, g, b); - u_palette[x] = COMPUTE_U(r, g, b); - v_palette[x] = COMPUTE_V(r, g, b); - } - - for(y = 0; y < img->height; y++) { - src = sy; - for(x = 0; x < img->width; x++) { - pixel = *src++; - - this->yuv.y[plane_ptr] = y_palette[pixel]; - this->yuv.u[plane_ptr] = u_palette[pixel]; - this->yuv.v[plane_ptr] = v_palette[pixel]; - plane_ptr++; - } - sy += this->av_frame->linesize[0]; - } - - yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]); - - } else { - - for (y=0; yheight; y++) { - xine_fast_memcpy (dy, sy, img->width); - - dy += img->pitches[0]; - - sy += this->av_frame->linesize[0]; - } - - for (y=0; y<(img->height/2); y++) { - - if (this->context->pix_fmt != PIX_FMT_YUV444P) { - - xine_fast_memcpy (du, su, img->width/2); - xine_fast_memcpy (dv, sv, img->width/2); - - } else { - - int x; - uint8_t *src; - uint8_t *dst; - - /* subsample */ - - src = su; dst = du; - for (x=0; x<(img->width/2); x++) { - *dst = *src; - dst++; - src += 2; - } - src = sv; dst = dv; - for (x=0; x<(img->width/2); x++) { - *dst = *src; - dst++; - src += 2; - } - - } - - du += img->pitches[1]; - dv += img->pitches[2]; - - if (this->context->pix_fmt != PIX_FMT_YUV420P) { - su += 2*this->av_frame->linesize[1]; - sv += 2*this->av_frame->linesize[2]; - } else { - su += this->av_frame->linesize[1]; - sv += this->av_frame->linesize[2]; - } - } - } -} - -static void ff_check_bufsize (ff_video_decoder_t *this, int size) { - if (size > this->bufsize) { - this->bufsize = size + size / 2; - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n"), - this->bufsize); - this->buf = realloc(this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE ); - } -} - -static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { - int codec_type; - - lprintf ("preview buffer\n"); - - codec_type = buf->type & 0xFFFF0000; - if (codec_type == BUF_VIDEO_MPEG) { - this->is_mpeg12 = 1; - if ( this->mpeg_parser == NULL ) { - this->mpeg_parser = xine_xmalloc(sizeof(mpeg_parser_t)); - mpeg_parser_init(this->mpeg_parser); - this->decoder_init_mode = 0; - } - } - - if (this->decoder_init_mode && !this->is_mpeg12) { - init_video_codec(this, codec_type); - init_postprocess(this); - this->decoder_init_mode = 0; - } -} - -static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *buf) { - - lprintf ("header buffer\n"); - - /* accumulate data */ - ff_check_bufsize(this, this->size + buf->size); - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - int codec_type; - - lprintf ("header complete\n"); - codec_type = buf->type & 0xFFFF0000; - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - - lprintf("standard header\n"); - - /* init package containing bih */ - memcpy ( &this->bih, this->buf, sizeof(xine_bmiheader) ); - - if (this->bih.biSize > sizeof(xine_bmiheader)) { - this->context->extradata_size = this->bih.biSize - sizeof(xine_bmiheader); - this->context->extradata = malloc(this->context->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(this->context->extradata, this->buf + sizeof(xine_bmiheader), - this->context->extradata_size); - } - - this->context->bits_per_sample = this->bih.biBitCount; - - } else { - - switch (codec_type) { - case BUF_VIDEO_RV10: - case BUF_VIDEO_RV20: - this->bih.biWidth = _X_BE_16(&this->buf[12]); - this->bih.biHeight = _X_BE_16(&this->buf[14]); - - this->context->sub_id = _X_BE_32(&this->buf[30]); - - this->context->slice_offset = xine_xmalloc(sizeof(int)*SLICE_OFFSET_SIZE); - this->slice_offset_size = SLICE_OFFSET_SIZE; - - lprintf("w=%d, h=%d\n", this->bih.biWidth, this->bih.biHeight); - - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_video_dec: unknown header for buf type 0x%X\n", codec_type); - return; - } - } - - /* reset accumulator */ - this->size = 0; - } -} - -static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *buf) { - /* take care of all the various types of special buffers - * note that order is important here */ - lprintf("special buffer\n"); - - if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM && - !this->context->extradata_size) { - - lprintf("BUF_SPECIAL_STSD_ATOM\n"); - this->context->extradata_size = buf->decoder_info[2]; - this->context->extradata = xine_xmalloc(buf->decoder_info[2] + - FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(this->context->extradata, buf->decoder_info_ptr[2], - buf->decoder_info[2]); - - } else if (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG && - !this->context->extradata_size) { - - lprintf("BUF_SPECIAL_DECODER_CONFIG\n"); - this->context->extradata_size = buf->decoder_info[2]; - this->context->extradata = xine_xmalloc(buf->decoder_info[2] + - FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(this->context->extradata, buf->decoder_info_ptr[2], - buf->decoder_info[2]); - - } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) { - unsigned int i; - - palette_entry_t *demuxer_palette; - AVPaletteControl *decoder_palette; - - lprintf("BUF_SPECIAL_PALETTE\n"); - this->context->palctrl = &this->palette_control; - decoder_palette = (AVPaletteControl *)this->context->palctrl; - demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2]; - - for (i = 0; i < buf->decoder_info[2]; i++) { - decoder_palette->palette[i] = - (demuxer_palette[i].r << 16) | - (demuxer_palette[i].g << 8) | - (demuxer_palette[i].b << 0); - } - decoder_palette->palette_changed = 1; - - } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) { - int i; - - lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n"); - this->context->slice_count = buf->decoder_info[2]+1; - - lprintf("slice_count=%d\n", this->context->slice_count); - - if(this->context->slice_count > this->slice_offset_size) { - this->context->slice_offset = realloc(this->context->slice_offset, - sizeof(int)*this->context->slice_count); - this->slice_offset_size = this->context->slice_count; - } - - for(i = 0; i < this->context->slice_count; i++) { - this->context->slice_offset[i] = - ((uint32_t *) buf->decoder_info_ptr[2])[(2*i)+1]; - lprintf("slice_offset[%d]=%d\n", i, this->context->slice_offset[i]); - } - } -} - -static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *buf) { - - vo_frame_t *img; - int free_img; - int got_picture, len; - int offset = 0; - int flush = 0; - int size = buf->size; - - lprintf("handle_mpeg12_buffer\n"); - - while ((size > 0) || (flush == 1)) { - - uint8_t *current; - int next_flush; - - got_picture = 0; - if (!flush) { - current = mpeg_parser_decode_data(this->mpeg_parser, - buf->content + offset, buf->content + offset + size, - &next_flush); - } else { - current = buf->content + offset + size; /* end of the buffer */ - next_flush = 0; - } - if (current == NULL) { - lprintf("current == NULL\n"); - return; - } - - if (this->mpeg_parser->has_sequence) { - ff_handle_mpeg_sequence(this, this->mpeg_parser); - } - - if (!this->decoder_ok) - return; - - if (flush) { - lprintf("flush lavc buffers\n"); - /* hack: ffmpeg outputs the last frame if size=0 */ - this->mpeg_parser->buffer_size = 0; - } - - /* skip decoding b frames if too late */ - this->context->hurry_up = (this->skipframes > 0); - - lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser->buffer_size); - len = avcodec_decode_video (this->context, this->av_frame, - &got_picture, this->mpeg_parser->chunk_buffer, - this->mpeg_parser->buffer_size); - lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n", - len, got_picture); - len = current - buf->content - offset; - lprintf("avcodec_decode_video: consumed_size=%d\n", len); - - flush = next_flush; - - if ((len < 0) || (len > buf->size)) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_video_dec: error decompressing frame\n"); - size = 0; /* draw a bad frame and exit */ - } else { - size -= len; - offset += len; - } - - if (got_picture && this->av_frame->data[0]) { - /* got a picture, draw it */ - if(!this->av_frame->opaque) { - /* indirect rendering */ - img = this->stream->video_out->get_frame (this->stream->video_out, - this->bih.biWidth, - this->bih.biHeight, - this->aspect_ratio, - this->output_format, - VO_BOTH_FIELDS|this->frame_flags); - free_img = 1; - } else { - /* DR1 */ - img = (vo_frame_t*) this->av_frame->opaque; - free_img = 0; - } - - img->pts = this->pts; - this->pts = 0; - - if (this->av_frame->repeat_pict) - img->duration = this->video_step * 3 / 2; - else - img->duration = this->video_step; - - img->crop_right = this->crop_right; - img->crop_bottom = this->crop_bottom; - - this->skipframes = img->draw(img, this->stream); - - if(free_img) - img->free(img); - - } else { - - if (this->context->hurry_up) { - /* skipped frame, output a bad frame */ - img = this->stream->video_out->get_frame (this->stream->video_out, - this->bih.biWidth, - this->bih.biHeight, - this->aspect_ratio, - this->output_format, - VO_BOTH_FIELDS|this->frame_flags); - img->pts = 0; - img->duration = this->video_step; - img->bad_frame = 1; - this->skipframes = img->draw(img, this->stream); - img->free(img); - } - } - } -} - -static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { - uint8_t *chunk_buf = this->buf; - AVRational avr00 = {0, 1}; - - lprintf("handle_buffer\n"); - - if (!this->decoder_ok) { - if (this->decoder_init_mode) { - int codec_type = buf->type & 0xFFFF0000; - - /* init ffmpeg decoder */ - init_video_codec(this, codec_type); - init_postprocess(this); - this->decoder_init_mode = 0; - } else { - return; - } - } - - if (buf->decoder_flags & BUF_FLAG_FRAME_START) { - lprintf("BUF_FLAG_FRAME_START\n"); - this->size = 0; - } - - /* data accumulation */ - if (buf->size > 0) { - if ((this->size == 0) && - ((buf->size + FF_INPUT_BUFFER_PADDING_SIZE) < buf->max_size) && - (buf->decoder_flags & BUF_FLAG_FRAME_END)) { - /* buf contains a complete frame */ - /* no memcpy needed */ - chunk_buf = buf->content; - this->size = buf->size; - lprintf("no memcpy needed to accumulate data\n"); - } else { - /* copy data into our internal buffer */ - ff_check_bufsize(this, this->size + buf->size); - chunk_buf = this->buf; /* ff_check_bufsize might realloc this->buf */ - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - lprintf("accumulate data into this->buf\n"); - } - } - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - vo_frame_t *img; - int free_img; - int got_picture, len; - int got_one_picture = 0; - int offset = 0; - int codec_type = buf->type & 0xFFFF0000; - int video_step_to_use; - - /* pad input data */ - /* note: bitstream, alt bitstream reader or something will cause - * severe mpeg4 artifacts if padding is less than 32 bits. - */ - memset(&chunk_buf[this->size], 0, FF_INPUT_BUFFER_PADDING_SIZE); - - while (this->size > 0) { - - /* DV frames can be completely skipped */ - if( codec_type == BUF_VIDEO_DV && this->skipframes ) { - this->size = 0; - got_picture = 0; - } else { - /* skip decoding b frames if too late */ - this->context->hurry_up = (this->skipframes > 0); - - lprintf("buffer size: %d\n", this->size); - len = avcodec_decode_video (this->context, this->av_frame, - &got_picture, &chunk_buf[offset], - this->size); - lprintf("consumed size: %d, got_picture: %d\n", len, got_picture); - if ((len <= 0) || (len > this->size)) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_video_dec: error decompressing frame\n"); - this->size = 0; - - } else { - - offset += len; - this->size -= len; - - if (this->size > 0) { - ff_check_bufsize(this, this->size); - memmove (this->buf, &chunk_buf[offset], this->size); - chunk_buf = this->buf; - } - } - } - - /* use externally provided video_step or fall back to stream's time_base otherwise */ - video_step_to_use = (this->video_step || !this->context->time_base.den) ? this->video_step : (int)(90000ll * this->context->time_base.num / this->context->time_base.den); - - /* aspect ratio provided by ffmpeg, override previous setting */ - if ((this->aspect_ratio_prio < 2) && - av_cmp_q(this->context->sample_aspect_ratio, avr00)) { - - if (!this->bih.biWidth || !this->bih.biHeight) { - this->bih.biWidth = this->context->width; - this->bih.biHeight = this->context->height; - } - - this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * - (double)this->bih.biWidth / (double)this->bih.biHeight; - this->aspect_ratio_prio = 2; - lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio); - set_stream_info(this); - } - - if (got_picture && this->av_frame->data[0]) { - /* got a picture, draw it */ - got_one_picture = 1; - if(!this->av_frame->opaque) { - /* indirect rendering */ - - /* initialize the colorspace converter */ - if (!this->cs_convert_init) { - if ((this->context->pix_fmt == PIX_FMT_RGBA32) || - (this->context->pix_fmt == PIX_FMT_RGB565) || - (this->context->pix_fmt == PIX_FMT_RGB555) || - (this->context->pix_fmt == PIX_FMT_BGR24) || - (this->context->pix_fmt == PIX_FMT_RGB24) || - (this->context->pix_fmt == PIX_FMT_PAL8)) { - this->output_format = XINE_IMGFMT_YUY2; - init_yuv_planes(&this->yuv, this->bih.biWidth, this->bih.biHeight); - this->yuv_init = 1; - } - this->cs_convert_init = 1; - } - - if (this->aspect_ratio_prio == 0) { - this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; - this->aspect_ratio_prio = 1; - lprintf("default aspect ratio: %f\n", this->aspect_ratio); - set_stream_info(this); - } - - /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */ - img = this->stream->video_out->get_frame (this->stream->video_out, - (this->bih.biWidth + 15) & ~15, - (this->bih.biHeight + 15) & ~15, - this->aspect_ratio, - this->output_format, - VO_BOTH_FIELDS|this->frame_flags); - free_img = 1; - } else { - /* DR1 */ - img = (vo_frame_t*) this->av_frame->opaque; - free_img = 0; - } - - /* post processing */ - if(this->pp_quality != this->class->pp_quality) - pp_change_quality(this); - - if(this->pp_available && this->pp_quality) { - - if(this->av_frame->opaque) { - /* DR1 */ - img = this->stream->video_out->get_frame (this->stream->video_out, - (img->width + 15) & ~15, - (img->height + 15) & ~15, - this->aspect_ratio, - this->output_format, - VO_BOTH_FIELDS|this->frame_flags); - free_img = 1; - } - - pp_postprocess(this->av_frame->data, this->av_frame->linesize, - img->base, img->pitches, - img->width, img->height, - this->av_frame->qscale_table, this->av_frame->qstride, - this->pp_mode, this->pp_context, - this->av_frame->pict_type); - - } else if (!this->av_frame->opaque) { - /* colorspace conversion or copy */ - ff_convert_frame(this, img); - } - - img->pts = this->pts; - this->pts = 0; - - /* workaround for weird 120fps streams */ - if( video_step_to_use == 750 ) { - /* fallback to the VIDEO_PTS_MODE */ - video_step_to_use = 0; - } - - if (this->av_frame->repeat_pict) - img->duration = video_step_to_use * 3 / 2; - else - img->duration = video_step_to_use; - - /* additionally crop away the extra pixels due to adjusting frame size above */ - img->crop_right = this->crop_right + (img->width - this->bih.biWidth); - img->crop_bottom = this->crop_bottom + (img->height - this->bih.biHeight); - - /* transfer some more frame settings for deinterlacing */ - img->progressive_frame = !this->av_frame->interlaced_frame; - img->top_field_first = this->av_frame->top_field_first; - - this->skipframes = img->draw(img, this->stream); - - if(free_img) - img->free(img); - } - } - - /* workaround for demux_mpeg_pes sending fields as frames: - * do not generate a bad frame for the first field picture - */ - if (!got_one_picture && (this->size || this->video_step || this->assume_bad_field_picture)) { - /* skipped frame, output a bad frame (use size 16x16, when size still uninitialized) */ - img = this->stream->video_out->get_frame (this->stream->video_out, - (this->bih.biWidth <= 0) ? 16 : ((this->bih.biWidth + 15) & ~15), - (this->bih.biHeight <= 0) ? 16 : ((this->bih.biHeight + 15) & ~15), - this->aspect_ratio, - this->output_format, - VO_BOTH_FIELDS|this->frame_flags); - /* set PTS to allow early syncing */ - img->pts = this->pts; - this->pts = 0; - - img->duration = video_step_to_use; - - /* additionally crop away the extra pixels due to adjusting frame size above */ - img->crop_right = ((this->bih.biWidth <= 0) ? 0 : this->crop_right) + (img->width - this->bih.biWidth); - img->crop_bottom = ((this->bih.biHeight <= 0) ? 0 : this->crop_bottom) + (img->height - this->bih.biHeight); - - img->bad_frame = 1; - this->skipframes = img->draw(img, this->stream); - img->free(img); - } - - this->assume_bad_field_picture = !got_one_picture; - } -} - -static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; - - lprintf ("processing packet type = %08x, len = %d, decoder_flags=%08x\n", - buf->type, buf->size, buf->decoder_flags); - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_PREVIEW) { - - ff_handle_preview_buffer(this, buf); - - } else { - - if (buf->decoder_flags & BUF_FLAG_SPECIAL) { - - ff_handle_special_buffer(this, buf); - - } - - if (buf->decoder_flags & BUF_FLAG_HEADER) { - - ff_handle_header_buffer(this, buf); - - if (buf->decoder_flags & BUF_FLAG_ASPECT) { - if (this->aspect_ratio_prio < 3) { - this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; - this->aspect_ratio_prio = 3; - lprintf("aspect ratio: %f\n", this->aspect_ratio); - set_stream_info(this); - } - } - - } else { - - /* decode */ - if (buf->pts) - this->pts = buf->pts; - - if (this->is_mpeg12) { - ff_handle_mpeg12_buffer(this, buf); - } else { - ff_handle_buffer(this, buf); - } - - } - } -} - -static void ff_flush (video_decoder_t *this_gen) { - lprintf ("ff_flush\n"); -} - -static void ff_reset (video_decoder_t *this_gen) { - ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; - - lprintf ("ff_reset\n"); - - this->size = 0; - - if(this->context && this->decoder_ok) - avcodec_flush_buffers(this->context); - - if (this->is_mpeg12) - mpeg_parser_reset(this->mpeg_parser); -} - -static void ff_discontinuity (video_decoder_t *this_gen) { - ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; - - lprintf ("ff_discontinuity\n"); - this->pts = 0; -} - -static void ff_dispose (video_decoder_t *this_gen) { - ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; - - lprintf ("ff_dispose\n"); - - if (this->decoder_ok) { - xine_list_iterator_t it; - AVFrame *av_frame; - - pthread_mutex_lock(&ffmpeg_lock); - avcodec_close (this->context); - pthread_mutex_unlock(&ffmpeg_lock); - - /* frame garbage collector here - workaround for buggy ffmpeg codecs that - * don't release their DR1 frames */ - while( (it = xine_list_front(this->dr1_frames)) != NULL ) - { - av_frame = (AVFrame *)xine_list_get_value(this->dr1_frames, it); - release_buffer(this->context, av_frame); - } - - this->stream->video_out->close(this->stream->video_out, this->stream); - this->decoder_ok = 0; - } - - if(this->context && this->context->slice_offset) - free(this->context->slice_offset); - - if(this->context && this->context->extradata) - free(this->context->extradata); - - if(this->yuv_init) - free_yuv_planes(&this->yuv); - - if( this->context ) - free( this->context ); - - if( this->av_frame ) - free( this->av_frame ); - - if (this->buf) - free(this->buf); - this->buf = NULL; - - if(this->pp_context) - pp_free_context(this->pp_context); - - if(this->pp_mode) - pp_free_mode(this->pp_mode); - - mpeg_parser_dispose(this->mpeg_parser); - - xine_list_delete(this->dr1_frames); - - free (this_gen); -} - -static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - ff_video_decoder_t *this ; - - lprintf ("open_plugin\n"); - - this = (ff_video_decoder_t *) xine_xmalloc (sizeof (ff_video_decoder_t)); - - this->video_decoder.decode_data = ff_decode_data; - this->video_decoder.flush = ff_flush; - this->video_decoder.reset = ff_reset; - this->video_decoder.discontinuity = ff_discontinuity; - this->video_decoder.dispose = ff_dispose; - this->size = 0; - - this->stream = stream; - this->class = (ff_video_class_t *) class_gen; - - this->av_frame = avcodec_alloc_frame(); - this->context = avcodec_alloc_context(); - this->context->opaque = this; - this->context->palctrl = NULL; - - this->decoder_ok = 0; - this->decoder_init_mode = 1; - this->buf = xine_xmalloc(VIDEOBUFSIZE + FF_INPUT_BUFFER_PADDING_SIZE); - this->bufsize = VIDEOBUFSIZE; - - this->is_mpeg12 = 0; - this->aspect_ratio = 0; - - this->pp_quality = 0; - this->pp_context = NULL; - this->pp_mode = NULL; - - this->mpeg_parser = NULL; - - this->dr1_frames = xine_list_new(); - - return &this->video_decoder; -} - -void *init_video_plugin (xine_t *xine, void *data) { - - ff_video_class_t *this; - config_values_t *config; - - this = (ff_video_class_t *) xine_xmalloc (sizeof (ff_video_class_t)); - - this->decoder_class.open_plugin = ff_video_open_plugin; - this->decoder_class.identifier = "ffmpeg video"; - this->decoder_class.description = N_("ffmpeg based video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - this->xine = xine; - - pthread_once( &once_control, init_once_routine ); - - /* Configuration for post processing quality - default to mid (3) for the - * moment */ - config = xine->config; - - this->pp_quality = xine->config->register_range(config, "video.processing.ffmpeg_pp_quality", 3, - 0, PP_QUALITY_MAX, - _("MPEG-4 postprocessing quality"), - _("You can adjust the amount of post processing applied to MPEG-4 video.\n" - "Higher values result in better quality, but need more CPU. Lower values may " - "result in image defects like block artifacts. For high quality content, " - "too heavy post processing can actually make the image worse by blurring it " - "too much."), - 10, pp_quality_cb, this); - - this->thread_count = xine->config->register_num(config, "video.processing.ffmpeg_thread_count", 1, - _("FFmpeg video decoding thread count"), - _("You can adjust the number of video decoding threads which FFmpeg may use.\n" - "Higher values should speed up decoding but it depends on the codec used " - "whether parallel decoding is supported. A rule of thumb is to have one " - "decoding thread per logical CPU (typically 1 to 4). A change will take " - "effect with playing the next stream."), - 10, thread_count_cb, this); - - return this; -} - -static uint32_t supported_video_types[] = { -#if defined(HAVE_FFMPEG) || CONFIG_MSMPEG4V1_DECODER - BUF_VIDEO_MSMPEG4_V1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MSMPEG4V2_DECODER - BUF_VIDEO_MSMPEG4_V2, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MSMPEG4V3_DECODER - BUF_VIDEO_MSMPEG4_V3, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WMV1_DECODER - BUF_VIDEO_WMV7, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WMV2_DECODER - BUF_VIDEO_WMV8, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WMV3_DECODER - BUF_VIDEO_WMV9, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VC1_DECODER - BUF_VIDEO_VC1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER - BUF_VIDEO_MPEG4, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER - BUF_VIDEO_XVID, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER - BUF_VIDEO_DIVX5, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MPEG4_DECODER - BUF_VIDEO_3IVX, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MJPEG_DECODER - BUF_VIDEO_JPEG, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MJPEG_DECODER - BUF_VIDEO_MJPEG, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MJPEGB_DECODER - BUF_VIDEO_MJPEG_B, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_H263I_DECODER - BUF_VIDEO_I263, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_H263_DECODER - BUF_VIDEO_H263, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_RV10_DECODER - BUF_VIDEO_RV10, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_RV20_DECODER - BUF_VIDEO_RV20, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_INDEO3_DECODER - BUF_VIDEO_IV31, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_INDEO3_DECODER - BUF_VIDEO_IV32, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_SVQ1_DECODER - BUF_VIDEO_SORENSON_V1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_SVQ3_DECODER - BUF_VIDEO_SORENSON_V3, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_DVVIDEO_DECODER - BUF_VIDEO_DV, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_HUFFYUV_DECODER - BUF_VIDEO_HUFFYUV, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VP3_DECODER - BUF_VIDEO_VP31, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VP5_DECODER - BUF_VIDEO_VP5, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VP6_DECODER - BUF_VIDEO_VP6, - BUF_VIDEO_VP6F, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_4XM_DECODER - BUF_VIDEO_4XM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_CINEPAK_DECODER - BUF_VIDEO_CINEPAK, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MSVIDEO1_DECODER - BUF_VIDEO_MSVC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MSRLE_DECODER - BUF_VIDEO_MSRLE, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_RPZA_DECODER - BUF_VIDEO_RPZA, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_CYUV_DECODER - BUF_VIDEO_CYUV, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ROQ_DECODER - BUF_VIDEO_ROQ, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_IDCIN_DECODER - BUF_VIDEO_IDCIN, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_XAN_WC3_DECODER - BUF_VIDEO_WC3, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WS_VQA_DECODER - BUF_VIDEO_VQA, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_INTERPLAY_VIDEO_DECODER - BUF_VIDEO_INTERPLAY, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_FLIC_DECODER - BUF_VIDEO_FLI, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_8BPS_DECODER - BUF_VIDEO_8BPS, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_SMC_DECODER - BUF_VIDEO_SMC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_TRUEMOTION1_DECODER - BUF_VIDEO_DUCKTM1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_TRUEMOTION2_DECODER - BUF_VIDEO_DUCKTM2, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VMDVIDEO_DECODER - BUF_VIDEO_VMD, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ZLIB_DECODER - BUF_VIDEO_ZLIB, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MSZH_DECODER - BUF_VIDEO_MSZH, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ASV1_DECODER - BUF_VIDEO_ASV1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ASV2_DECODER - BUF_VIDEO_ASV2, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VCR1_DECODER - BUF_VIDEO_ATIVCR1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_FLV_DECODER - BUF_VIDEO_FLV1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_QTRLE_DECODER - BUF_VIDEO_QTRLE, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_H264_DECODER - BUF_VIDEO_H264, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_H261_DECODER - BUF_VIDEO_H261, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_AASC_DECODER - BUF_VIDEO_AASC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_LOCO_DECODER - BUF_VIDEO_LOCO, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_QDRAW_DECODER - BUF_VIDEO_QDRW, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_QPEG_DECODER - BUF_VIDEO_QPEG, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_TSCC_DECODER - BUF_VIDEO_TSCC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ULTI_DECODER - BUF_VIDEO_ULTI, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_WNV1_DECODER - BUF_VIDEO_WNV1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_VIXL_DECODER - BUF_VIDEO_XL, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_INDEO2_DECODER - BUF_VIDEO_RT21, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_FRAPS_DECODER - BUF_VIDEO_FPS1, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MPEG1VIDEO_DECODER - BUF_VIDEO_MPEG, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_CSCD_DECODER - BUF_VIDEO_CSCD, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_AVS_DECODER - BUF_VIDEO_AVS, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_MMVIDEO_DECODER - BUF_VIDEO_ALGMM, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_ZMBV_DECODER - BUF_VIDEO_ZMBV, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_SMACKVIDEO_DECODER - BUF_VIDEO_SMACKER, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_NUV_DECODER - BUF_VIDEO_NUV, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_KMVC_DECODER - BUF_VIDEO_KMVC, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_FLASHSV_DECODER - BUF_VIDEO_FLASHSV, -#endif -#if defined(HAVE_FFMPEG) || CONFIG_CAVS_DECODER - BUF_VIDEO_CAVS, -#endif - BUF_VIDEO_THEORA_RAW, - 0 -}; - -static uint32_t wmv8_video_types[] = { - BUF_VIDEO_WMV8, - 0 -}; - -static uint32_t wmv9_video_types[] = { - BUF_VIDEO_WMV9, - 0 -}; - -decoder_info_t dec_info_ffmpeg_video = { - supported_video_types, /* supported types */ - 6 /* priority */ -}; - -decoder_info_t dec_info_ffmpeg_wmv8 = { - wmv8_video_types, /* supported types */ - 0 /* priority */ -}; - -decoder_info_t dec_info_ffmpeg_wmv9 = { - wmv9_video_types, /* supported types */ - 0 /* priority */ -}; diff --git a/src/libffmpeg/ffmpeg_decoder.c b/src/libffmpeg/ffmpeg_decoder.c deleted file mode 100644 index 8a8a79270..000000000 --- a/src/libffmpeg/ffmpeg_decoder.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2001-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine decoder plugin using ffmpeg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "ffmpeg_decoder.h" - -/* - * common initialisation - */ - -pthread_once_t once_control = PTHREAD_ONCE_INIT; -pthread_mutex_t ffmpeg_lock; - -void init_once_routine(void) { - pthread_mutex_init(&ffmpeg_lock, NULL); - avcodec_init(); - avcodec_register_all(); -} - -/* - * exported plugin catalog entry - */ - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 19, "ffmpegvideo", XINE_VERSION_CODE, &dec_info_ffmpeg_video, init_video_plugin }, - { PLUGIN_VIDEO_DECODER, 19, "ffmpeg-wmv8", XINE_VERSION_CODE, &dec_info_ffmpeg_wmv8, init_video_plugin }, - { PLUGIN_VIDEO_DECODER, 19, "ffmpeg-wmv9", XINE_VERSION_CODE, &dec_info_ffmpeg_wmv9, init_video_plugin }, - { PLUGIN_AUDIO_DECODER, 16, "ffmpegaudio", XINE_VERSION_CODE, &dec_info_ffmpeg_audio, init_audio_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libffmpeg/ffmpeg_decoder.h b/src/libffmpeg/ffmpeg_decoder.h deleted file mode 100644 index bfe71a6b1..000000000 --- a/src/libffmpeg/ffmpeg_decoder.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2001-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#ifndef HAVE_XINE_DECODER_H -#define HAVE_XINE_DECODER_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -typedef struct ff_codec_s { - uint32_t type; - enum CodecID id; - const char *name; -} ff_codec_t; - -void *init_audio_plugin (xine_t *xine, void *data); -void *init_video_plugin (xine_t *xine, void *data); - -extern decoder_info_t dec_info_ffmpeg_video; -extern decoder_info_t dec_info_ffmpeg_wmv8; -extern decoder_info_t dec_info_ffmpeg_wmv9; -extern decoder_info_t dec_info_ffmpeg_audio; - -extern pthread_once_t once_control; -void init_once_routine(void); - -extern pthread_mutex_t ffmpeg_lock; - -#endif diff --git a/src/libffmpeg/ffmpeg_encoder.c b/src/libffmpeg/ffmpeg_encoder.c deleted file mode 100644 index 7fe65c7fa..000000000 --- a/src/libffmpeg/ffmpeg_encoder.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -/* mpeg encoders for the dxr3 video out plugin. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "dxr3_mpeg_encoder" -/* #define LOG_VERBOSE */ -/* #define LOG */ - -#include "video_out_dxr3.h" - -#include - -/* buffer size for encoded mpeg1 stream; will hold one intra frame - * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ -#define DEFAULT_BUFFER_SIZE 512*1024 - - -/*initialisation function, used by the dxr3 plugin */ -int dxr3_encoder_init(dxr3_driver_t *drv) EXPORTED; - -/* functions required by encoder api */ -static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame); -static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame); -static int lavc_on_unneeded(dxr3_driver_t *drv); - -/*encoder structure*/ -typedef struct lavc_data_s { - encoder_data_t encoder_data; - AVCodecContext *context; /* handle for encoding */ - int width, height; /* width and height of the video frame */ - uint8_t *ffmpeg_buffer; /* lavc buffer */ - AVFrame *picture; /* picture to be encoded */ - uint8_t *out[3]; /* aligned buffer for YV12 data */ - uint8_t *buf; /* unaligned YV12 buffer */ -} lavc_data_t; - - -int dxr3_encoder_init(dxr3_driver_t *drv) -{ - lavc_data_t* this; - avcodec_init(); - - avcodec_register_all(); - lprintf("lavc init , version %x\n", avcodec_version()); - this = xine_xmalloc(sizeof(lavc_data_t)); - if (!this) return 0; - - this->encoder_data.type = ENC_LAVC; - this->encoder_data.on_update_format = lavc_on_update_format; - this->encoder_data.on_frame_copy = NULL; - this->encoder_data.on_display_frame = lavc_on_display_frame; - this->encoder_data.on_unneeded = lavc_on_unneeded; - this->context = 0; - - drv->enc = &this->encoder_data; - return 1; -} - -/* helper function */ -static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame); - -static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) -{ - lavc_data_t *this = (lavc_data_t *)drv->enc; - AVCodec *codec; - unsigned char use_quantizer; - - if (this->context) { - avcodec_close(this->context); - free(this->context); - free(this->picture); - this->context = NULL; - this->picture = NULL; - } - - /* if YUY2 and dimensions changed, we need to re-allocate the - * internal YV12 buffer */ - if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { - int image_size = frame->vo_frame.pitches[0] * frame->oheight; - - this->out[0] = xine_xmalloc_aligned(16, image_size * 3/2, - (void *)&this->buf); - this->out[1] = this->out[0] + image_size; - this->out[2] = this->out[1] + image_size/4; - - /* fill with black (yuv 16,128,128) */ - memset(this->out[0], 16, image_size); - memset(this->out[1], 128, image_size/4); - memset(this->out[2], 128, image_size/4); - lprintf("Using YUY2->YV12 conversion\n"); - } - - /* resolution must be a multiple of two */ - if ((frame->vo_frame.pitches[0] % 2 != 0) || (frame->oheight % 2 != 0)) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: lavc only handles video dimensions which are multiples of 2\n"); - return 0; - } - - /* get mpeg codec handle */ - codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); - if (!codec) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: lavc MPEG1 codec not found\n"); - return 0; - } - lprintf("lavc MPEG1 encoder found.\n"); - - this->width = frame->vo_frame.pitches[0]; - this->height = frame->oheight; - - this->context = avcodec_alloc_context(); - if (!this->context) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: Couldn't start the ffmpeg library\n"); - return 0; - } - this->picture = avcodec_alloc_frame(); - if (!this->picture) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: Couldn't allocate ffmpeg frame\n"); - return 0; - } - - /* mpeg1 encoder only support YUV420P */ - this->context->pix_fmt = PIX_FMT_YUVJ420P; - - /* put sample parameters */ - this->context->bit_rate = drv->class->xine->config->register_range(drv->class->xine->config, - "dxr3.encoding.lavc_bitrate", 10000, 1000, 20000, - _("libavcodec mpeg output bitrate (kbit/s)"), - _("The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " - "Higher values will increase quality and CPU usage.\n" - "This setting is only considered, when constant quality mode is disabled."), 10, NULL, NULL); - this->context->bit_rate *= 1000; /* config in kbit/s, libavcodec wants bit/s */ - - use_quantizer = drv->class->xine->config->register_bool(drv->class->xine->config, - "dxr3.encoding.lavc_quantizer", 1, - _("constant quality mode"), - _("When enabled, libavcodec will use a constant quality mode by dynamically " - "compressing the images based on their complexity. When disabled, libavcodec " - "will use constant bitrate mode."), 10, NULL, NULL); - - if (use_quantizer) { - this->context->qmin = drv->class->xine->config->register_range(drv->class->xine->config, - "dxr3.encoding.lavc_qmin", 1, 1, 10, - _("minimum compression"), - _("The minimum compression to apply to an image in constant quality mode."), - 10, NULL, NULL); - - this->context->qmax = drv->class->xine->config->register_range(drv->class->xine->config, - "dxr3.encoding.lavc_qmax", 2, 1, 20, - _("maximum quantizer"), - _("The maximum compression to apply to an image in constant quality mode."), - 10, NULL, NULL); - } - - lprintf("lavc -> bitrate %d \n", this->context->bit_rate); - - this->context->width = frame->vo_frame.pitches[0]; - this->context->height = frame->oheight; - - this->context->gop_size = 0; /*intra frames only */ - this->context->me_method = ME_ZERO; /*motion estimation type*/ - - this->context->time_base.den = 90000; - if (frame->vo_frame.duration > 90000 / 24) - this->context->time_base.num = 90000 / 24; - else if (frame->vo_frame.duration < 90000 / 60) - this->context->time_base.num = 90000 / 60; - else - this->context->time_base.num = frame->vo_frame.duration; - /* ffmpeg can complain about illegal framerates, but since this seems no - * problem for the DXR3, we just tell ffmpeg to be more lax with */ - this->context->strict_std_compliance = -1; - - /* open avcodec */ - if (avcodec_open(this->context, codec) < 0) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: could not open codec\n"); - return 0; - } - lprintf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n"); - - if (!this->ffmpeg_buffer) - this->ffmpeg_buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); /* why allocate more than needed ?! */ - if (!this->ffmpeg_buffer) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); - return 0; - } - - return 1; -} - -static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) -{ - int size; - lavc_data_t* this = (lavc_data_t *)drv->enc; - ssize_t written; - - if (frame->vo_frame.bad_frame) return 1; - /* ignore old frames */ - if ((frame->vo_frame.pitches[0] != this->context->width) || (frame->oheight != this->context->height)) { - frame->vo_frame.free(&frame->vo_frame); - lprintf("LAVC ignoring frame !!!\n"); - return 1; - } - - /* prepare frame for conversion, handles YUY2 -> YV12 conversion when necessary */ - lavc_prepare_frame(this, drv, frame); - - /* do the encoding */ - size = avcodec_encode_video(this->context, this->ffmpeg_buffer, DEFAULT_BUFFER_SIZE, this->picture); - - frame->vo_frame.free(&frame->vo_frame); - - if (size < 0) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: encoding failed\n"); - return 0; - } - - written = write(drv->fd_video, this->ffmpeg_buffer, size); - if (written < 0) { - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); - return 0; - } - if (written != size) - xprintf(drv->class->xine, XINE_VERBOSITY_LOG, - "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, size); - return 1; -} - -static int lavc_on_unneeded(dxr3_driver_t *drv) -{ - lavc_data_t *this = (lavc_data_t *)drv->enc; - lprintf("flushing buffers\n"); - if (this->context) { - avcodec_close(this->context); - free(this->context); - free(this->picture); - this->context = NULL; - this->picture = NULL; - } - return 1; -} - -static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame) -{ - int i, j, w2; - uint8_t *yuy2; - - if (frame->vo_frame.bad_frame) return 1; - - if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { - /* need YUY2->YV12 conversion */ - if (!(this->out[0] && this->out[1] && this->out[2]) ) { - lprintf("Internal YV12 buffer not created.\n"); - return 0; - } - this->picture->data[0] = this->out[0] + frame->vo_frame.pitches[0] * drv->top_bar; /* y */ - this->picture->data[1] = this->out[1] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* u */ - this->picture->data[2] = this->out[2] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* v */ - yuy2 = frame->vo_frame.base[0]; - w2 = frame->vo_frame.pitches[0] / 2; - for (i = 0; i < frame->vo_frame.height; i += 2) { - for (j = 0; j < w2; j++) { - /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */ - *(this->picture->data[0]++) = *(yuy2++); - *(this->picture->data[1]++) = *(yuy2++); - *(this->picture->data[0]++) = *(yuy2++); - *(this->picture->data[2]++) = *(yuy2++); - } - /* down sampling */ - for (j = 0; j < w2; j++) { - /* skip every second line for U and V */ - *(this->picture->data[0]++) = *(yuy2++); - yuy2++; - *(this->picture->data[0]++) = *(yuy2++); - yuy2++; - } - } - /* reset for encoder */ - this->picture->data[0] = this->out[0]; - this->picture->data[1] = this->out[1]; - this->picture->data[2] = this->out[2]; - } - else { /* YV12 **/ - this->picture->data[0] = frame->real_base[0]; - this->picture->data[1] = frame->real_base[1]; - this->picture->data[2] = frame->real_base[2]; - } - this->picture->linesize[0] = this->context->width; - this->picture->linesize[1] = this->context->width / 2; - this->picture->linesize[2] = this->context->width / 2; - return 1; -} -- cgit v1.2.3 From b7a18f2d1b7afe26d1816621178a52c527d773f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 23:24:00 +0100 Subject: Move libmpeg2 inside video_dec/libmpeg2. --HG-- rename : src/libmpeg2/Makefile.am => src/video_dec/libmpeg2/Makefile.am rename : src/libmpeg2/cpu_state.c => src/video_dec/libmpeg2/cpu_state.c rename : src/libmpeg2/decode.c => src/video_dec/libmpeg2/decode.c rename : src/libmpeg2/header.c => src/video_dec/libmpeg2/header.c rename : src/libmpeg2/idct.c => src/video_dec/libmpeg2/idct.c rename : src/libmpeg2/idct_altivec.c => src/video_dec/libmpeg2/idct_altivec.c rename : src/libmpeg2/idct_mlib.c => src/video_dec/libmpeg2/idct_mlib.c rename : src/libmpeg2/idct_mlib.h => src/video_dec/libmpeg2/idct_mlib.h rename : src/libmpeg2/idct_mmx.c => src/video_dec/libmpeg2/idct_mmx.c rename : src/libmpeg2/libmpeg2_accel.c => src/video_dec/libmpeg2/libmpeg2_accel.c rename : src/libmpeg2/libmpeg2_accel.h => src/video_dec/libmpeg2/libmpeg2_accel.h rename : src/libmpeg2/motion_comp.c => src/video_dec/libmpeg2/motion_comp.c rename : src/libmpeg2/motion_comp_altivec.c => src/video_dec/libmpeg2/motion_comp_altivec.c rename : src/libmpeg2/motion_comp_mlib.c => src/video_dec/libmpeg2/motion_comp_mlib.c rename : src/libmpeg2/motion_comp_mmx.c => src/video_dec/libmpeg2/motion_comp_mmx.c rename : src/libmpeg2/motion_comp_vis.c => src/video_dec/libmpeg2/motion_comp_vis.c rename : src/libmpeg2/mpeg2.h => src/video_dec/libmpeg2/mpeg2.h rename : src/libmpeg2/mpeg2_internal.h => src/video_dec/libmpeg2/mpeg2_internal.h rename : src/libmpeg2/slice.c => src/video_dec/libmpeg2/slice.c rename : src/libmpeg2/slice_xvmc.c => src/video_dec/libmpeg2/slice_xvmc.c rename : src/libmpeg2/slice_xvmc_vld.c => src/video_dec/libmpeg2/slice_xvmc_vld.c rename : src/libmpeg2/stats.c => src/video_dec/libmpeg2/stats.c rename : src/libmpeg2/vis.h => src/video_dec/libmpeg2/vis.h rename : src/libmpeg2/vlc.h => src/video_dec/libmpeg2/vlc.h rename : src/libmpeg2/xine_mpeg2_decoder.c => src/video_dec/libmpeg2/xine_mpeg2_decoder.c rename : src/libmpeg2/xvmc.h => src/video_dec/libmpeg2/xvmc.h rename : src/libmpeg2/xvmc_vld.h => src/video_dec/libmpeg2/xvmc_vld.h --- src/Makefile.am | 1 - src/libmpeg2/Makefile.am | 32 - src/libmpeg2/cpu_state.c | 183 --- src/libmpeg2/decode.c | 1009 ------------- src/libmpeg2/header.c | 411 ----- src/libmpeg2/idct.c | 348 ----- src/libmpeg2/idct_altivec.c | 233 --- src/libmpeg2/idct_mlib.c | 62 - src/libmpeg2/idct_mlib.h | 25 - src/libmpeg2/idct_mmx.c | 740 --------- src/libmpeg2/libmpeg2_accel.c | 223 --- src/libmpeg2/libmpeg2_accel.h | 48 - src/libmpeg2/motion_comp.c | 154 -- src/libmpeg2/motion_comp_altivec.c | 2031 ------------------------- src/libmpeg2/motion_comp_mlib.c | 181 --- src/libmpeg2/motion_comp_mmx.c | 1012 ------------- src/libmpeg2/motion_comp_vis.c | 2059 -------------------------- src/libmpeg2/mpeg2.h | 98 -- src/libmpeg2/mpeg2_internal.h | 294 ---- src/libmpeg2/slice.c | 1833 ----------------------- src/libmpeg2/slice_xvmc.c | 1988 ------------------------- src/libmpeg2/slice_xvmc_vld.c | 225 --- src/libmpeg2/stats.c | 317 ---- src/libmpeg2/vis.h | 328 ---- src/libmpeg2/vlc.h | 428 ------ src/libmpeg2/xine_mpeg2_decoder.c | 169 --- src/libmpeg2/xvmc.h | 32 - src/libmpeg2/xvmc_vld.h | 32 - src/video_dec/Makefile.am | 2 + src/video_dec/libmpeg2/Makefile.am | 32 + src/video_dec/libmpeg2/cpu_state.c | 183 +++ src/video_dec/libmpeg2/decode.c | 1009 +++++++++++++ src/video_dec/libmpeg2/header.c | 411 +++++ src/video_dec/libmpeg2/idct.c | 348 +++++ src/video_dec/libmpeg2/idct_altivec.c | 233 +++ src/video_dec/libmpeg2/idct_mlib.c | 62 + src/video_dec/libmpeg2/idct_mlib.h | 25 + src/video_dec/libmpeg2/idct_mmx.c | 740 +++++++++ src/video_dec/libmpeg2/libmpeg2_accel.c | 223 +++ src/video_dec/libmpeg2/libmpeg2_accel.h | 48 + src/video_dec/libmpeg2/motion_comp.c | 154 ++ src/video_dec/libmpeg2/motion_comp_altivec.c | 2031 +++++++++++++++++++++++++ src/video_dec/libmpeg2/motion_comp_mlib.c | 181 +++ src/video_dec/libmpeg2/motion_comp_mmx.c | 1012 +++++++++++++ src/video_dec/libmpeg2/motion_comp_vis.c | 2059 ++++++++++++++++++++++++++ src/video_dec/libmpeg2/mpeg2.h | 98 ++ src/video_dec/libmpeg2/mpeg2_internal.h | 294 ++++ src/video_dec/libmpeg2/slice.c | 1833 +++++++++++++++++++++++ src/video_dec/libmpeg2/slice_xvmc.c | 1988 +++++++++++++++++++++++++ src/video_dec/libmpeg2/slice_xvmc_vld.c | 225 +++ src/video_dec/libmpeg2/stats.c | 317 ++++ src/video_dec/libmpeg2/vis.h | 328 ++++ src/video_dec/libmpeg2/vlc.h | 428 ++++++ src/video_dec/libmpeg2/xine_mpeg2_decoder.c | 169 +++ src/video_dec/libmpeg2/xvmc.h | 32 + src/video_dec/libmpeg2/xvmc_vld.h | 32 + 56 files changed, 14497 insertions(+), 14496 deletions(-) delete mode 100644 src/libmpeg2/Makefile.am delete mode 100644 src/libmpeg2/cpu_state.c delete mode 100644 src/libmpeg2/decode.c delete mode 100644 src/libmpeg2/header.c delete mode 100644 src/libmpeg2/idct.c delete mode 100644 src/libmpeg2/idct_altivec.c delete mode 100644 src/libmpeg2/idct_mlib.c delete mode 100644 src/libmpeg2/idct_mlib.h delete mode 100644 src/libmpeg2/idct_mmx.c delete mode 100644 src/libmpeg2/libmpeg2_accel.c delete mode 100644 src/libmpeg2/libmpeg2_accel.h delete mode 100644 src/libmpeg2/motion_comp.c delete mode 100644 src/libmpeg2/motion_comp_altivec.c delete mode 100644 src/libmpeg2/motion_comp_mlib.c delete mode 100644 src/libmpeg2/motion_comp_mmx.c delete mode 100644 src/libmpeg2/motion_comp_vis.c delete mode 100644 src/libmpeg2/mpeg2.h delete mode 100644 src/libmpeg2/mpeg2_internal.h delete mode 100644 src/libmpeg2/slice.c delete mode 100644 src/libmpeg2/slice_xvmc.c delete mode 100644 src/libmpeg2/slice_xvmc_vld.c delete mode 100644 src/libmpeg2/stats.c delete mode 100644 src/libmpeg2/vis.h delete mode 100644 src/libmpeg2/vlc.h delete mode 100644 src/libmpeg2/xine_mpeg2_decoder.c delete mode 100644 src/libmpeg2/xvmc.h delete mode 100644 src/libmpeg2/xvmc_vld.h create mode 100644 src/video_dec/libmpeg2/Makefile.am create mode 100644 src/video_dec/libmpeg2/cpu_state.c create mode 100644 src/video_dec/libmpeg2/decode.c create mode 100644 src/video_dec/libmpeg2/header.c create mode 100644 src/video_dec/libmpeg2/idct.c create mode 100644 src/video_dec/libmpeg2/idct_altivec.c create mode 100644 src/video_dec/libmpeg2/idct_mlib.c create mode 100644 src/video_dec/libmpeg2/idct_mlib.h create mode 100644 src/video_dec/libmpeg2/idct_mmx.c create mode 100644 src/video_dec/libmpeg2/libmpeg2_accel.c create mode 100644 src/video_dec/libmpeg2/libmpeg2_accel.h create mode 100644 src/video_dec/libmpeg2/motion_comp.c create mode 100644 src/video_dec/libmpeg2/motion_comp_altivec.c create mode 100644 src/video_dec/libmpeg2/motion_comp_mlib.c create mode 100644 src/video_dec/libmpeg2/motion_comp_mmx.c create mode 100644 src/video_dec/libmpeg2/motion_comp_vis.c create mode 100644 src/video_dec/libmpeg2/mpeg2.h create mode 100644 src/video_dec/libmpeg2/mpeg2_internal.h create mode 100644 src/video_dec/libmpeg2/slice.c create mode 100644 src/video_dec/libmpeg2/slice_xvmc.c create mode 100644 src/video_dec/libmpeg2/slice_xvmc_vld.c create mode 100644 src/video_dec/libmpeg2/stats.c create mode 100644 src/video_dec/libmpeg2/vis.h create mode 100644 src/video_dec/libmpeg2/vlc.h create mode 100644 src/video_dec/libmpeg2/xine_mpeg2_decoder.c create mode 100644 src/video_dec/libmpeg2/xvmc.h create mode 100644 src/video_dec/libmpeg2/xvmc_vld.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 4b16acb35..a94673fb7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,6 @@ SUBDIRS = \ dxr3 \ input \ demuxers \ - libmpeg2 \ libspudec \ libspucc \ libspucmml \ diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am deleted file mode 100644 index d772f0e09..000000000 --- a/src/libmpeg2/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -noinst_HEADERS = vlc.h mpeg2.h xvmc.h xvmc_vld.h mpeg2_internal.h idct_mlib.h vis.h \ - libmpeg2_accel.h - -xineplug_LTLIBRARIES = xineplug_decode_mpeg2.la - -xineplug_decode_mpeg2_la_SOURCES = \ - cpu_state.c \ - decode.c \ - header.c \ - idct.c \ - idct_altivec.c \ - idct_mlib.c \ - idct_mmx.c \ - motion_comp.c \ - motion_comp_altivec.c \ - motion_comp_mmx.c \ - motion_comp_mlib.c \ - motion_comp_vis.c \ - slice.c \ - slice_xvmc.c \ - slice_xvmc_vld.c \ - stats.c \ - xine_mpeg2_decoder.c \ - libmpeg2_accel.c - -xineplug_decode_mpeg2_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) -lm -xineplug_decode_mpeg2_la_CFLAGS = $(AM_CFLAGS) $(MLIB_CFLAGS) diff --git a/src/libmpeg2/cpu_state.c b/src/libmpeg2/cpu_state.c deleted file mode 100644 index 12963644c..000000000 --- a/src/libmpeg2/cpu_state.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * cpu_state.c - * Copyright (C) 2000-2003 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#include -#include - -#include "mpeg2_internal.h" -#include - -void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; -void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; - -#if defined(ARCH_X86) || defined(ARCH_X86_64) -static void state_restore_mmx (cpu_state_t * state) -{ - emms (); -} -#endif - -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) - -#ifndef HOST_OS_DARWIN - -static void state_save_altivec (cpu_state_t * state) -{ - asm (" \n" - " li %r9, 16 \n" - " stvx %v20, 0, %r3 \n" - " li %r11, 32 \n" - " stvx %v21, %r9, %r3 \n" - " li %r9, 48 \n" - " stvx %v22, %r11, %r3 \n" - " li %r11, 64 \n" - " stvx %v23, %r9, %r3 \n" - " li %r9, 80 \n" - " stvx %v24, %r11, %r3 \n" - " li %r11, 96 \n" - " stvx %v25, %r9, %r3 \n" - " li %r9, 112 \n" - " stvx %v26, %r11, %r3 \n" - " li %r11, 128 \n" - " stvx %v27, %r9, %r3 \n" - " li %r9, 144 \n" - " stvx %v28, %r11, %r3 \n" - " li %r11, 160 \n" - " stvx %v29, %r9, %r3 \n" - " li %r9, 176 \n" - " stvx %v30, %r11, %r3 \n" - " stvx %v31, %r9, %r3 \n" - ); -} - -static void state_restore_altivec (cpu_state_t * state) -{ - asm (" \n" - " li %r9, 16 \n" - " lvx %v20, 0, %r3 \n" - " li %r11, 32 \n" - " lvx %v21, %r9, %r3 \n" - " li %r9, 48 \n" - " lvx %v22, %r11, %r3 \n" - " li %r11, 64 \n" - " lvx %v23, %r9, %r3 \n" - " li %r9, 80 \n" - " lvx %v24, %r11, %r3 \n" - " li %r11, 96 \n" - " lvx %v25, %r9, %r3 \n" - " li %r9, 112 \n" - " lvx %v26, %r11, %r3 \n" - " li %r11, 128 \n" - " lvx %v27, %r9, %r3 \n" - " li %r9, 144 \n" - " lvx %v28, %r11, %r3 \n" - " li %r11, 160 \n" - " lvx %v29, %r9, %r3 \n" - " li %r9, 176 \n" - " lvx %v30, %r11, %r3 \n" - " lvx %v31, %r9, %r3 \n" - ); -} - -#else /* HOST_OS_DARWIN */ - -#define LI(a,b) "li r" #a "," #b "\n\t" -#define STVX0(a,b,c) "stvx v" #a ",0,r" #c "\n\t" -#define STVX(a,b,c) "stvx v" #a ",r" #b ",r" #c "\n\t" -#define LVX0(a,b,c) "lvx v" #a ",0,r" #c "\n\t" -#define LVX(a,b,c) "lvx v" #a ",r" #b ",r" #c "\n\t" - -static void state_save_altivec (cpu_state_t * state) -{ - asm (LI (9, 16) - STVX0 (20, 0, 3) - LI (11, 32) - STVX (21, 9, 3) - LI (9, 48) - STVX (22, 11, 3) - LI (11, 64) - STVX (23, 9, 3) - LI (9, 80) - STVX (24, 11, 3) - LI (11, 96) - STVX (25, 9, 3) - LI (9, 112) - STVX (26, 11, 3) - LI (11, 128) - STVX (27, 9, 3) - LI (9, 144) - STVX (28, 11, 3) - LI (11, 160) - STVX (29, 9, 3) - LI (9, 176) - STVX (30, 11, 3) - STVX (31, 9, 3)); -} - -static void state_restore_altivec (cpu_state_t * state) -{ - asm (LI (9, 16) - LVX0 (20, 0, 3) - LI (11, 32) - LVX (21, 9, 3) - LI (9, 48) - LVX (22, 11, 3) - LI (11, 64) - LVX (23, 9, 3) - LI (9, 80) - LVX (24, 11, 3) - LI (11, 96) - LVX (25, 9, 3) - LI (9, 112) - LVX (26, 11, 3) - LI (11, 128) - LVX (27, 9, 3) - LI (9, 144) - LVX (28, 11, 3) - LI (11, 160) - LVX (29, 9, 3) - LI (9, 176) - LVX (30, 11, 3) - LVX (31, 9, 3)); -} -#endif /* HOST_OS_DARWIN */ - -#endif /* defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) */ - -void mpeg2_cpu_state_init (uint32_t mm_accel) -{ -#if defined(ARCH_X86) || defined(ARCH_X86_64) - if (mm_accel & MM_ACCEL_X86_MMX) { - mpeg2_cpu_state_restore = state_restore_mmx; - } -#endif -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) - if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { - mpeg2_cpu_state_save = state_save_altivec; - mpeg2_cpu_state_restore = state_restore_altivec; - } -#endif -} - diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c deleted file mode 100644 index 145d5f58b..000000000 --- a/src/libmpeg2/decode.c +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * decode.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - * - * xine-specific version by G. Bartsch - * - */ - -#include "config.h" -#include -#include /* memcpy/memset, try to remove */ -#include -#include -#include - -#define LOG_MODULE "decode" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include "mpeg2.h" -#include "mpeg2_internal.h" -#include -#include "libmpeg2_accel.h" - -/* -#define LOG_PAN_SCAN -*/ - -/* #define BUFFER_SIZE (224 * 1024) */ -#define BUFFER_SIZE (1194 * 1024) /* new buffer size for mpeg2dec 0.2.1 */ - -static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); - -void mpeg2_init (mpeg2dec_t * mpeg2dec, - xine_video_port_t * output) -{ - static int do_init = 1; - uint32_t mm_accel; - - if (do_init) { - do_init = 0; - mm_accel = xine_mm_accel(); - mpeg2_cpu_state_init (mm_accel); - mpeg2_idct_init (mm_accel); - mpeg2_mc_init (mm_accel); - libmpeg2_accel_scan(&mpeg2dec->accel, mpeg2_scan_norm, mpeg2_scan_alt); - } - - if( !mpeg2dec->chunk_buffer ) - mpeg2dec->chunk_buffer = xine_xmalloc_aligned (16, BUFFER_SIZE + 4, - &mpeg2dec->chunk_base); - if( !mpeg2dec->picture ) - mpeg2dec->picture = xine_xmalloc_aligned (16, sizeof (picture_t), - &mpeg2dec->picture_base); - - mpeg2dec->shift = 0xffffff00; - mpeg2dec->new_sequence = 0; - mpeg2dec->is_sequence_needed = 1; - mpeg2dec->is_wait_for_ip_frames = 2; - mpeg2dec->frames_to_drop = 0; - mpeg2dec->drop_frame = 0; - mpeg2dec->in_slice = 0; - mpeg2dec->output = output; - mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; - mpeg2dec->code = 0xb4; - mpeg2dec->seek_mode = 0; - - /* initialize AFD storage */ - mpeg2dec->afd_value_seen = XINE_VIDEO_AFD_NOT_PRESENT; - mpeg2dec->afd_value_reported = (XINE_VIDEO_AFD_NOT_PRESENT - 1); - - memset (mpeg2dec->picture, 0, sizeof (picture_t)); - - /* initialize substructures */ - mpeg2_header_state_init (mpeg2dec->picture); - - if ( output->get_capabilities(output) & VO_CAP_XXMC) { - printf("libmpeg2: output port has XxMC capability\n"); - mpeg2dec->frame_format = XINE_IMGFMT_XXMC; - } else if( output->get_capabilities(output) & VO_CAP_XVMC_MOCOMP) { - printf("libmpeg2: output port has XvMC capability\n"); - mpeg2dec->frame_format = XINE_IMGFMT_XVMC; - } else { - mpeg2dec->frame_format = XINE_IMGFMT_YV12; - } -} - -static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) -{ - static const double durations[] = { - 0, /* invalid */ - 3753.75, /* 23.976 fps */ - 3750, /* 24 fps */ - 3600, /* 25 fps */ - 3003, /* 29.97 fps */ - 3000, /* 30 fps */ - 1800, /* 50 fps */ - 1501.5, /* 59.94 fps */ - 1500, /* 60 fps */ - }; - double duration = ((unsigned) mpeg2dec->picture->frame_rate_code > 8u) - ? 0 : durations[mpeg2dec->picture->frame_rate_code]; - - duration = duration * (mpeg2dec->picture->frame_rate_ext_n + 1.0) / - (mpeg2dec->picture->frame_rate_ext_d + 1.0); - - /* this should be used to detect any special rff pattern */ - mpeg2dec->rff_pattern = mpeg2dec->rff_pattern << 1; - mpeg2dec->rff_pattern |= !!frame->repeat_first_field; - - if( ((mpeg2dec->rff_pattern & 0xff) == 0xaa || - (mpeg2dec->rff_pattern & 0xff) == 0x55) && - !mpeg2dec->picture->progressive_sequence ) { - /* special case for ntsc 3:2 pulldown */ - duration *= 5.0 / 4.0; - } - else - { - if( frame->repeat_first_field ) { - if( !mpeg2dec->picture->progressive_sequence && - frame->progressive_frame ) { - /* decoder should output 3 fields, so adjust duration to - count on this extra field time */ - duration *= 3.0 / 2.0; - } else if( mpeg2dec->picture->progressive_sequence ) { - /* for progressive sequences the output should repeat the - frame 1 or 2 times depending on top_field_first flag. */ - duration *= (frame->top_field_first) ? 3 : 2; - } - } - } - - frame->duration = (int) ceil (duration); - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, frame->duration); - /*printf("mpeg2dec: rff=%u\n",frame->repeat_first_field);*/ -} - -static double get_aspect_ratio(mpeg2dec_t *mpeg2dec) -{ - double ratio; - picture_t * picture = mpeg2dec->picture; - double mpeg1_pel_ratio[16] = {1.0 /* forbidden */, - 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, - 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ }; - - /* TODO: For slower machines the value of this function should be computed - * once and cached! - */ - - if( !picture->mpeg1 ) { - /* these hardcoded values are defined on mpeg2 standard for - * aspect ratio. other values are reserved or forbidden. */ - switch(picture->aspect_ratio_information) { - case 2: - ratio = 4.0/3.0; - break; - case 3: - ratio = 16.0/9.0; - break; - case 4: - ratio = 2.11/1.0; - break; - case 1: - default: - ratio = (double)picture->coded_picture_width/(double)picture->coded_picture_height; - break; - } - } else { - /* mpeg1 constants refer to pixel aspect ratio */ - ratio = (double)picture->coded_picture_width/(double)picture->coded_picture_height; - ratio /= mpeg1_pel_ratio[picture->aspect_ratio_information]; - } - - return ratio; -} - -static void remember_metainfo (mpeg2dec_t *mpeg2dec) { - - picture_t * picture = mpeg2dec->picture; - - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, picture->display_width); - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, picture->display_height); - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_RATIO, - ((double)10000 * get_aspect_ratio(mpeg2dec))); - - switch (mpeg2dec->picture->frame_rate_code) { - case 1: /* 23.976 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3913); - break; - case 2: /* 24 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3750); - break; - case 3: /* 25 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3600); - break; - case 4: /* 29.97 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3003); - break; - case 5: /* 30 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3000); - break; - case 6: /* 50 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1800); - break; - case 7: /* 59.94 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1525); - break; - case 8: /* 60 fps */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1509); - break; - default: - /* printf ("invalid/unknown frame rate code : %d \n", - frame->frame_rate_code); */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3000); - } - - _x_meta_info_set_utf8(mpeg2dec->stream, XINE_META_INFO_VIDEOCODEC, "MPEG (libmpeg2)"); -} - -static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, - uint8_t * buffer, int next_code) -{ - picture_t * picture; - int is_frame_done; - double ratio; - - /* wait for sequence_header_code */ - if (mpeg2dec->is_sequence_needed) { - if (code != 0xb3) { - /* printf ("libmpeg2: waiting for sequence header\n"); */ - mpeg2dec->pts = 0; - return 0; - } - } - if (mpeg2dec->is_frame_needed) { - /* printf ("libmpeg2: waiting for frame start\n"); */ - mpeg2dec->pts = 0; - if (mpeg2dec->picture->current_frame) - mpeg2dec->picture->current_frame->bad_frame = 1; - } - - mpeg2_stats (code, buffer); - - picture = mpeg2dec->picture; - is_frame_done = mpeg2dec->in_slice && ((!code) || (code >= 0xb0)); - - if (is_frame_done) - mpeg2dec->in_slice = 0; - - if (is_frame_done && picture->current_frame != NULL) { - - libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format, - picture, code); - - if (((picture->picture_structure == FRAME_PICTURE) || - (picture->second_field)) ) { - - if (mpeg2dec->drop_frame) - picture->current_frame->bad_frame = 1; - - if (picture->picture_coding_type == B_TYPE) { - if( picture->current_frame && !picture->current_frame->drawn ) { - - /* hack against wrong mpeg1 pts */ - if (picture->mpeg1) - picture->current_frame->pts = 0; - - get_frame_duration(mpeg2dec, picture->current_frame); - mpeg2dec->frames_to_drop = picture->current_frame->draw (picture->current_frame, mpeg2dec->stream); - picture->current_frame->drawn = 1; - } - } else if (picture->forward_reference_frame && !picture->forward_reference_frame->drawn) { - get_frame_duration(mpeg2dec, picture->forward_reference_frame); - mpeg2dec->frames_to_drop = picture->forward_reference_frame->draw (picture->forward_reference_frame, - mpeg2dec->stream); - picture->forward_reference_frame->drawn = 1; - } - } - } - - switch (code) { - case 0x00: /* picture_start_code */ - if (mpeg2_header_picture (picture, buffer)) { - fprintf (stderr, "bad picture header\n"); - abort(); - } - - mpeg2dec->is_frame_needed=0; - - if (!picture->second_field) { - /* find out if we want to skip this frame */ - mpeg2dec->drop_frame = 0; - - /* picture->skip_non_intra_dct = (mpeg2dec->frames_to_drop>0) ; */ - - switch (picture->picture_coding_type) { - case B_TYPE: - - lprintf ("B-Frame\n"); - - if (mpeg2dec->frames_to_drop>1) { - lprintf ("dropping b-frame because frames_to_drop==%d\n", - mpeg2dec->frames_to_drop); - mpeg2dec->drop_frame = 1; - } else if (!picture->forward_reference_frame || picture->forward_reference_frame->bad_frame - || !picture->backward_reference_frame || picture->backward_reference_frame->bad_frame) { -#ifdef LOG - printf ("libmpeg2: dropping b-frame because ref is bad ("); - if (picture->forward_reference_frame) - printf ("fw ref frame %d, bad %d;", picture->forward_reference_frame->id, - picture->forward_reference_frame->bad_frame); - else - printf ("fw ref frame not there;"); - if (picture->backward_reference_frame) - printf ("bw ref frame %d, bad %d)\n", picture->backward_reference_frame->id, - picture->backward_reference_frame->bad_frame); - else - printf ("fw ref frame not there)\n"); -#endif - mpeg2dec->drop_frame = 1; - } else if (mpeg2dec->is_wait_for_ip_frames > 0) { - lprintf("dropping b-frame because refs are invalid\n"); - mpeg2dec->drop_frame = 1; - } - break; - - case P_TYPE: - - lprintf ("P-Frame\n"); - - if (mpeg2dec->frames_to_drop>2) { - mpeg2dec->drop_frame = 1; - lprintf ("dropping p-frame because frames_to_drop==%d\n", - mpeg2dec->frames_to_drop); - } else if (!picture->backward_reference_frame || picture->backward_reference_frame->bad_frame) { - mpeg2dec->drop_frame = 1; -#ifdef LOG - if (!picture->backward_reference_frame) - printf ("libmpeg2: dropping p-frame because no ref frame\n"); - else - printf ("libmpeg2: dropping p-frame because ref %d is bad\n", picture->backward_reference_frame->id); -#endif - } else if (mpeg2dec->is_wait_for_ip_frames > 1) { - lprintf("dropping p-frame because ref is invalid\n"); - mpeg2dec->drop_frame = 1; - } else if (mpeg2dec->is_wait_for_ip_frames) - mpeg2dec->is_wait_for_ip_frames--; - - break; - - case I_TYPE: - lprintf ("I-Frame\n"); - /* for the sake of dvd menus, never drop i-frames - if (mpeg2dec->frames_to_drop>4) { - mpeg2dec->drop_frame = 1; - } - */ - - if (mpeg2dec->is_wait_for_ip_frames) - mpeg2dec->is_wait_for_ip_frames--; - - break; - } - } - - break; - - case 0xb2: /* user data code */ - process_userdata(mpeg2dec, buffer); - break; - - case 0xb3: /* sequence_header_code */ - if (mpeg2_header_sequence (picture, buffer)) { - fprintf (stderr, "bad sequence header\n"); - /* abort(); */ - break; - } - - /* reset AFD value to detect absence */ - mpeg2dec->afd_value_seen = XINE_VIDEO_AFD_NOT_PRESENT; - - /* according to ISO/IEC 13818-2, an extension start code will follow. - * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */ - picture->mpeg1 = (next_code != 0xb5); - - if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect; - - if (mpeg2dec->is_sequence_needed ) { - mpeg2dec->new_sequence = 1; - } - - if (mpeg2dec->is_sequence_needed - || (picture->aspect_ratio_information != picture->saved_aspect_ratio) - || (picture->frame_width != picture->coded_picture_width) - || (picture->frame_height != picture->coded_picture_height)) { - xine_event_t event; - xine_format_change_data_t data; - - remember_metainfo (mpeg2dec); - event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; - event.stream = mpeg2dec->stream; - event.data = &data; - event.data_length = sizeof(data); - data.width = picture->coded_picture_width; - data.height = picture->coded_picture_height; - data.aspect = picture->aspect_ratio_information; - data.pan_scan = mpeg2dec->force_pan_scan; - xine_event_send(mpeg2dec->stream, &event); - - _x_stream_info_set(mpeg2dec->stream,XINE_STREAM_INFO_VIDEO_WIDTH, - picture->display_width); - _x_stream_info_set(mpeg2dec->stream,XINE_STREAM_INFO_VIDEO_HEIGHT, - picture->display_height); - - if (picture->forward_reference_frame && - picture->forward_reference_frame != picture->current_frame && - picture->forward_reference_frame != picture->backward_reference_frame) - picture->forward_reference_frame->free (picture->forward_reference_frame); - - if (picture->backward_reference_frame && - picture->backward_reference_frame != picture->current_frame) - picture->backward_reference_frame->free (picture->backward_reference_frame); - - mpeg2dec->is_sequence_needed = 0; - picture->forward_reference_frame = NULL; - picture->backward_reference_frame = NULL; - - picture->frame_width = picture->coded_picture_width; - picture->frame_height = picture->coded_picture_height; - picture->saved_aspect_ratio = picture->aspect_ratio_information; - } - break; - - case 0xb5: /* extension_start_code */ - if (mpeg2_header_extension (picture, buffer)) { - fprintf (stderr, "bad extension\n"); - abort(); - } - break; - - case 0xb7: /* sequence end code */ -#ifdef LOG_PAN_SCAN - printf ("libmpeg2: sequence end code not handled\n"); -#endif - case 0xb8: /* group of pictures start code */ - if (mpeg2_header_group_of_pictures (picture, buffer)) { - printf ("libmpeg2: bad group of pictures\n"); - abort(); - } - default: - if ((code >= 0xb9) && (code != 0xe4)) { - printf("Not multiplexed? 0x%x\n",code); - } - if (code >= 0xb0) - break; - - /* check for AFD change once per picture */ - if (mpeg2dec->afd_value_reported != mpeg2dec->afd_value_seen) { - /* AFD data should better be stored in current_frame to have it */ - /* ready and synchronous with other data like width or height. */ - /* An AFD change should then be detected when a new frame is emitted */ - /* from the decoder to report the AFD change in display order and not */ - /* in decoding order like it happens below for now. */ - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_AFD, mpeg2dec->afd_value_seen); - lprintf ("AFD changed from %d to %d\n", mpeg2dec->afd_value_reported, mpeg2dec->afd_value_seen); - mpeg2dec->afd_value_reported = mpeg2dec->afd_value_seen; - } - - if (!(mpeg2dec->in_slice)) { - mpeg2dec->in_slice = 1; - - if (picture->second_field) { - if (picture->current_frame) - picture->current_frame->field(picture->current_frame, - picture->picture_structure); - else - mpeg2dec->drop_frame = 1; - } else { - int flags = picture->picture_structure; - - if (!picture->mpeg1) flags |= VO_INTERLACED_FLAG; - if (mpeg2dec->force_pan_scan) flags |= VO_PAN_SCAN_FLAG; - if (mpeg2dec->new_sequence) flags |= VO_NEW_SEQUENCE_FLAG; - - if ( picture->current_frame && - picture->current_frame != picture->backward_reference_frame && - picture->current_frame != picture->forward_reference_frame ) { - picture->current_frame->free (picture->current_frame); - } - if (picture->picture_coding_type == B_TYPE) { - ratio = get_aspect_ratio(mpeg2dec); - picture->current_frame = - mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out, - picture->coded_picture_width, - picture->coded_picture_height, - ratio, - mpeg2dec->frame_format, - flags); - libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, - picture, ratio, flags); - } else { - ratio = get_aspect_ratio(mpeg2dec); - picture->current_frame = - mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out, - picture->coded_picture_width, - picture->coded_picture_height, - ratio, - mpeg2dec->frame_format, - flags); - - libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, - picture, ratio, flags); - - if (picture->forward_reference_frame && - picture->forward_reference_frame != picture->backward_reference_frame) - picture->forward_reference_frame->free (picture->forward_reference_frame); - - picture->forward_reference_frame = - picture->backward_reference_frame; - picture->backward_reference_frame = picture->current_frame; - } - - if(mpeg2dec->new_sequence) - mpeg2dec->new_sequence = - libmpeg2_accel_new_sequence(&mpeg2dec->accel, mpeg2dec->frame_format, - picture); - - picture->current_frame->bad_frame = 1; - picture->current_frame->drawn = 0; - picture->current_frame->pts = mpeg2dec->pts; - picture->current_frame->top_field_first = picture->top_field_first; - picture->current_frame->repeat_first_field = picture->repeat_first_field; - picture->current_frame->progressive_frame = picture->progressive_frame; - picture->current_frame->crop_right = picture->coded_picture_width - picture->display_width; - picture->current_frame->crop_bottom = picture->coded_picture_height - picture->display_height; - - switch( picture->picture_coding_type ) { - case I_TYPE: - picture->current_frame->picture_coding_type = XINE_PICT_I_TYPE; - break; - case P_TYPE: - picture->current_frame->picture_coding_type = XINE_PICT_P_TYPE; - break; - case B_TYPE: - picture->current_frame->picture_coding_type = XINE_PICT_B_TYPE; - break; - case D_TYPE: - picture->current_frame->picture_coding_type = XINE_PICT_D_TYPE; - break; - } - - lprintf ("decoding frame %d, type %s\n", - picture->current_frame->id, picture->picture_coding_type == I_TYPE ? "I" : - picture->picture_coding_type == P_TYPE ? "P" : "B"); - mpeg2dec->pts = 0; - /*printf("Starting to decode frame %d\n",picture->current_frame->id);*/ - } - } - - if (!mpeg2dec->drop_frame && picture->current_frame != NULL) { -#ifdef DEBUG_LOG - printf("slice target %08x past %08x future %08x\n",picture->current_frame,picture->forward_reference_frame,picture->backward_reference_frame); - fflush(stdout); -#endif - libmpeg2_accel_slice(&mpeg2dec->accel, picture, code, buffer, mpeg2dec->chunk_size, - mpeg2dec->chunk_buffer); - - if( picture->v_offset > picture->limit_y || - picture->v_offset + 16 > picture->display_height ) { - picture->current_frame->bad_frame = 0; - } - } - } - - /* printf ("libmpeg2: parse_chunk %d completed\n", code); */ - return is_frame_done; -} - -static inline int find_start_code (mpeg2dec_t * mpeg2dec, - uint8_t ** current, uint8_t * limit) -{ - uint8_t * p; - - if (*current >= limit) - return 0; - if (mpeg2dec->shift == 0x00000100) - return 1; - - mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; - - if (*current >= limit) - return 0; - if (mpeg2dec->shift == 0x00000100) - return 1; - - mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; - - if (*current >= limit) - return 0; - if (mpeg2dec->shift == 0x00000100) - return 1; - - limit--; - - if (*current >= limit) { - mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; - return 0; - } - - p = *current; - - while (p < limit && (p = (uint8_t *)memchr(p, 0x01, limit - p))) { - if (p[-2] || p[-1]) - p += 3; - else { - *current = ++p; - return 1; - } - } - - *current = ++limit; - p = limit - 3; - mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; - mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; - mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; - - return 0; -} - -static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec, - uint8_t * current, uint8_t * end) -{ - uint8_t * limit; - uint8_t * data = current; - int found, bite; - - /* sequence end code 0xb7 doesn't have any data and there might be the case - * that no start code will follow this code for quite some time (e. g. in case - * of a still image. - * Therefore, return immediately with a chunk_size of 0. Setting code to 0xb4 - * will eat up any trailing garbage next time. - */ - if (mpeg2dec->code == 0xb7) { - mpeg2dec->code = 0xb4; - mpeg2dec->chunk_size = 0; - return current; - } - - limit = current + (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); - if (limit > end) - limit = end; - - found = find_start_code(mpeg2dec, ¤t, limit); - bite = current - data; - if (bite) { - xine_fast_memcpy(mpeg2dec->chunk_ptr, data, bite); - mpeg2dec->chunk_ptr += bite; - } - - if (found) { - mpeg2dec->code = *current++; - mpeg2dec->chunk_size = mpeg2dec->chunk_ptr - mpeg2dec->chunk_buffer - 3; - mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; - mpeg2dec->shift = 0xffffff00; - return current; - } - - if (current == end) - return NULL; - - /* we filled the chunk buffer without finding a start code */ - mpeg2dec->code = 0xb4; /* sequence_error_code */ - mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; - return current; -} - -int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end, - uint64_t pts) -{ - int ret; - uint8_t code; - - ret = 0; - if (mpeg2dec->seek_mode) { - mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; - mpeg2dec->code = 0xb4; - mpeg2dec->seek_mode = 0; - mpeg2dec->shift = 0xffffff00; - mpeg2dec->is_frame_needed = 1; - } - - if (pts) - mpeg2dec->pts = pts; - - while (current != end || mpeg2dec->code == 0xb7) { - code = mpeg2dec->code; - current = copy_chunk (mpeg2dec, current, end); - if (current == NULL) - break; - ret += parse_chunk (mpeg2dec, code, mpeg2dec->chunk_buffer, mpeg2dec->code); - } - - libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format, - mpeg2dec->picture, 0xff); - - return ret; -} - -void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec) { - picture_t *picture = mpeg2dec->picture; - - if( !picture ) - return; - - mpeg2dec->in_slice = 0; - mpeg2dec->pts = 0; - if ( picture->current_frame ) - picture->current_frame->pts = 0; - if ( picture->forward_reference_frame ) - picture->forward_reference_frame->pts = 0; - if ( picture->backward_reference_frame ) - picture->backward_reference_frame->pts = 0; - - libmpeg2_accel_discontinuity(&mpeg2dec->accel, mpeg2dec->frame_format, picture); -} - -void mpeg2_reset (mpeg2dec_t * mpeg2dec) { - - picture_t *picture = mpeg2dec->picture; - - if( !picture ) - return; - - mpeg2_discontinuity(mpeg2dec); - - if( !picture->mpeg1 ) { - mpeg2dec->is_wait_for_ip_frames = 2; - - /* mark current frames as bad so they won't make to screen */ - if ( picture->current_frame ) - picture->current_frame->bad_frame=1; - if (picture->forward_reference_frame ) - picture->forward_reference_frame->bad_frame=1; - if (picture->backward_reference_frame) - picture->backward_reference_frame->bad_frame=1; - - } else { - /* to free reference frames one also needs to fix slice.c to - * abort when they are NULL. unfortunately it seems to break - * DVD menus. - * - * ...so let's do this for mpeg-1 only :) - */ - if ( picture->current_frame && - picture->current_frame != picture->backward_reference_frame && - picture->current_frame != picture->forward_reference_frame ) - picture->current_frame->free (picture->current_frame); - picture->current_frame = NULL; - - if (picture->forward_reference_frame && - picture->forward_reference_frame != picture->backward_reference_frame) - picture->forward_reference_frame->free (picture->forward_reference_frame); - picture->forward_reference_frame = NULL; - - if (picture->backward_reference_frame) - picture->backward_reference_frame->free (picture->backward_reference_frame); - picture->backward_reference_frame = NULL; - } - - mpeg2dec->in_slice = 0; - mpeg2dec->seek_mode = 1; - -} - -void mpeg2_flush (mpeg2dec_t * mpeg2dec) { - - picture_t *picture = mpeg2dec->picture; - - if (!picture) - return; - - if (picture->current_frame && !picture->current_frame->drawn && - !picture->current_frame->bad_frame) { - - lprintf ("blasting out current frame %d on flush\n", - picture->current_frame->id); - - picture->current_frame->drawn = 1; - get_frame_duration(mpeg2dec, picture->current_frame); - - picture->current_frame->pts = 0; - picture->current_frame->draw(picture->current_frame, mpeg2dec->stream); - } - -} - -void mpeg2_close (mpeg2dec_t * mpeg2dec) -{ - picture_t *picture = mpeg2dec->picture; - - /* - { - static uint8_t finalizer[] = {0,0,1,0xb4}; - mpeg2_decode_data (mpeg2dec, finalizer, finalizer+4, 0); - } - */ - - /* - dont remove any picture->*->free() below. doing so will cause buffer - leak, and we only have about 15 of them. - */ - - if ( picture->current_frame ) { - if( !picture->current_frame->drawn ) { - lprintf ("blasting out current frame on close\n"); - picture->current_frame->pts = 0; - get_frame_duration(mpeg2dec, picture->current_frame); - picture->current_frame->draw (picture->current_frame, mpeg2dec->stream); - picture->current_frame->drawn = 1; - } - - if( picture->current_frame != picture->backward_reference_frame && - picture->current_frame != picture->forward_reference_frame ) { - picture->current_frame->free (picture->current_frame); - } - picture->current_frame = NULL; - } - - if (picture->forward_reference_frame && - picture->forward_reference_frame != picture->backward_reference_frame) { - picture->forward_reference_frame->free (picture->forward_reference_frame); - picture->forward_reference_frame = NULL; - } - - if (picture->backward_reference_frame) { - if( !picture->backward_reference_frame->drawn) { - lprintf ("blasting out backward reference frame on close\n"); - picture->backward_reference_frame->pts = 0; - get_frame_duration(mpeg2dec, picture->backward_reference_frame); - picture->backward_reference_frame->draw (picture->backward_reference_frame, mpeg2dec->stream); - picture->backward_reference_frame->drawn = 1; - } - picture->backward_reference_frame->free (picture->backward_reference_frame); - picture->backward_reference_frame = NULL; - } - - if ( mpeg2dec->chunk_buffer ) { - free (mpeg2dec->chunk_base); - mpeg2dec->chunk_buffer = NULL; - } - - if ( mpeg2dec->picture ) { - free (mpeg2dec->picture_base); - mpeg2dec->picture = NULL; - } - - if ( mpeg2dec->cc_dec) { - /* dispose the closed caption decoder */ - mpeg2dec->cc_dec->dispose(mpeg2dec->cc_dec); - mpeg2dec->cc_dec = NULL; - } -} - -void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec, - uint8_t * current, uint8_t * end){ - - uint8_t code, next_code; - picture_t *picture = mpeg2dec->picture; - - mpeg2dec->seek_mode = 1; - - while (current != end) { - code = mpeg2dec->code; - current = copy_chunk (mpeg2dec, current, end); - if (current == NULL) - return ; - next_code = mpeg2dec->code; - - /* printf ("looking for sequence header... %02x\n", code); */ - - mpeg2_stats (code, mpeg2dec->chunk_buffer); - - if (code == 0xb3) { /* sequence_header_code */ - if (mpeg2_header_sequence (picture, mpeg2dec->chunk_buffer)) { - printf ("libmpeg2: bad sequence header\n"); - continue; - } - - /* according to ISO/IEC 13818-2, an extension start code will follow. - * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */ - picture->mpeg1 = (next_code != 0xb5); - - if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect; - - if (mpeg2dec->is_sequence_needed) { - xine_event_t event; - xine_format_change_data_t data; - - mpeg2dec->new_sequence = 1; - - mpeg2dec->is_sequence_needed = 0; - picture->frame_width = picture->coded_picture_width; - picture->frame_height = picture->coded_picture_height; - - remember_metainfo (mpeg2dec); - - event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; - event.stream = mpeg2dec->stream; - event.data = &data; - event.data_length = sizeof(data); - data.width = picture->coded_picture_width; - data.height = picture->coded_picture_height; - data.aspect = picture->aspect_ratio_information; - data.pan_scan = mpeg2dec->force_pan_scan; - xine_event_send(mpeg2dec->stream, &event); - - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, - picture->display_width); - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, - picture->display_height); - } - } else if (code == 0xb5) { /* extension_start_code */ - if (mpeg2_header_extension (picture, mpeg2dec->chunk_buffer)) { - printf ("libmpeg2: bad extension\n"); - continue ; - } - } - } -} - -/* Find the end of the userdata field in an MPEG-2 stream */ -static uint8_t *find_end(uint8_t *buffer) -{ - uint8_t *current = buffer; - while(1) { - if (current[0] == 0 && current[1] == 0 && current[2] == 1) - break; - current++; - } - return current; -} - -static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer) -{ - /* check if user data denotes closed captions */ - if (buffer[0] == 'C' && buffer[1] == 'C') { - - if (!mpeg2dec->cc_dec) { - xine_event_t event; - xine_format_change_data_t data; - - /* open the closed caption decoder first */ - mpeg2dec->cc_dec = _x_get_spu_decoder(mpeg2dec->stream, (BUF_SPU_CC >> 16) & 0xff); - - /* send a frame format event so that the CC decoder knows the initial image size */ - event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; - event.stream = mpeg2dec->stream; - event.data = &data; - event.data_length = sizeof(data); - data.width = mpeg2dec->picture->coded_picture_width; - data.height = mpeg2dec->picture->coded_picture_height; - data.aspect = mpeg2dec->picture->aspect_ratio_information; - data.pan_scan = mpeg2dec->force_pan_scan; - xine_event_send(mpeg2dec->stream, &event); - - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, - mpeg2dec->picture->display_width); - _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, - mpeg2dec->picture->display_height); - } - - if (mpeg2dec->cc_dec) { - buf_element_t buf; - - buf.type = BUF_SPU_CC; - buf.content = &buffer[2]; - buf.pts = mpeg2dec->pts; - buf.size = find_end(buffer) - &buffer[2]; - buf.decoder_flags = 0; - - mpeg2dec->cc_dec->decode_data(mpeg2dec->cc_dec, &buf); - } - } - /* check Active Format Description ETSI TS 101 154 V1.5.1 */ - else if (buffer[0] == 0x44 && buffer[1] == 0x54 && buffer[2] == 0x47 && buffer[3] == 0x31) - mpeg2dec->afd_value_seen = (buffer[4] & 0x40) ? (buffer[5] & 0x0f) : XINE_VIDEO_AFD_NOT_PRESENT; -} diff --git a/src/libmpeg2/header.c b/src/libmpeg2/header.c deleted file mode 100644 index 12ba0ff8a..000000000 --- a/src/libmpeg2/header.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * header.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -/* -#define LOG_PAN_SCAN -*/ - -#include "config.h" - -#include /* For printf debugging */ -#include - -#include "mpeg2_internal.h" -#include - -/* default intra quant matrix, in zig-zag order */ -static const uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = { - 8, - 16, 16, - 19, 16, 19, - 22, 22, 22, 22, - 22, 22, 26, 24, 26, - 27, 27, 27, 26, 26, 26, - 26, 27, 27, 27, 29, 29, 29, - 34, 34, 34, 29, 29, 29, 27, 27, - 29, 29, 32, 32, 34, 34, 37, - 38, 37, 35, 35, 34, 35, - 38, 38, 40, 40, 40, - 48, 48, 46, 46, - 56, 56, 58, - 69, 69, - 83 -}; - -uint8_t mpeg2_scan_norm[64] ATTR_ALIGN(16) = -{ - /* Zig-Zag scan pattern */ - 0, 1, 8,16, 9, 2, 3,10, - 17,24,32,25,18,11, 4, 5, - 12,19,26,33,40,48,41,34, - 27,20,13, 6, 7,14,21,28, - 35,42,49,56,57,50,43,36, - 29,22,15,23,30,37,44,51, - 58,59,52,45,38,31,39,46, - 53,60,61,54,47,55,62,63 -}; - -uint8_t mpeg2_scan_alt[64] ATTR_ALIGN(16) = -{ - /* Alternate scan pattern */ - 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, - 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, - 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, - 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 -}; - -/* count must be between 1 and 32 */ -static uint32_t get_bits(uint8_t *buffer, uint32_t count, uint32_t *bit_position) { - uint32_t byte_offset; - uint32_t bit_offset; - uint32_t bit_mask; - uint32_t bit_bite; - uint32_t result=0; - if (count == 0) return 0; - do { - byte_offset = *bit_position >> 3; /* Div 8 */ - bit_offset = 8 - (*bit_position & 0x7); /* Bits got 87654321 */ - bit_mask = ((1 << (bit_offset)) - 1); - bit_bite = bit_offset; - if (count < bit_offset) { - bit_mask ^= ((1 << (bit_offset-count)) - 1); - bit_bite = count; - } - /* - printf("Byte=0x%02x Bitmask=0x%04x byte_offset=%u bit_offset=%u bit_byte=%u count=%u\n",buffer[byte_offset], bit_mask, byte_offset, bit_offset, bit_bite,count); - */ - result = (result << bit_bite) | ((buffer[byte_offset] & bit_mask) >> (bit_offset-bit_bite)); - *bit_position+=bit_bite; - count-=bit_bite; - } while ((count > 0) && (byte_offset<50) ); - return result; -} - -void mpeg2_header_state_init (picture_t * picture) -{ - picture->scan = mpeg2_scan_norm; - picture->load_intra_quantizer_matrix = 1; - picture->load_non_intra_quantizer_matrix = 1; -} - -int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer) -{ - int width, height; - int i; - - if ((buffer[6] & 0x20) != 0x20) - return 1; /* missing marker_bit */ - - height = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; - - picture->display_width = width = (height >> 12); - picture->display_height = height = (height & 0xfff); - - width = (width + 15) & ~15; - height = (height + 15) & ~15; - - if ((width > 1920) || (height > 1152)) - return 1; /* size restrictions for MP@HL */ - - picture->coded_picture_width = width; - picture->coded_picture_height = height; - - /* this is not used by the decoder */ - picture->aspect_ratio_information = buffer[3] >> 4; - picture->frame_rate_code = buffer[3] & 15; - picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6); - - if (buffer[7] & 2) { - for (i = 0; i < 64; i++) - picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = - (buffer[i+7] << 7) | (buffer[i+8] >> 1); - buffer += 64; - } else - for (i = 0; i < 64; i++) - picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = - default_intra_quantizer_matrix [i]; - - if (buffer[7] & 1) - for (i = 0; i < 64; i++) - picture->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = - buffer[i+8]; - else - for (i = 0; i < 64; i++) - picture->non_intra_quantizer_matrix[i] = 16; - picture->load_intra_quantizer_matrix = 1; - picture->load_non_intra_quantizer_matrix = 1; - /* MPEG1 - for testing only */ - picture->mpeg1 = 1; - picture->intra_dc_precision = 0; - picture->frame_pred_frame_dct = 1; - picture->q_scale_type = 0; - picture->concealment_motion_vectors = 0; - /* picture->alternate_scan = 0; */ - picture->picture_structure = FRAME_PICTURE; - /* picture->second_field = 0; */ - - return 0; -} - -static int sequence_extension (picture_t * picture, uint8_t * buffer) -{ - /* check chroma format, size extensions, marker bit */ - if (((buffer[1] & 0x07) != 0x02) || (buffer[2] & 0xe0) || - ((buffer[3] & 0x01) != 0x01)) - return 1; - - /* this is not used by the decoder */ - picture->progressive_sequence = (buffer[1] >> 3) & 1; - - picture->low_delay = buffer[5] & 0x80; - - if (!picture->progressive_sequence) - picture->coded_picture_height = - (picture->coded_picture_height + 31) & ~31; - - - /* printf ("libmpeg2: low_delay : %d\n", picture->low_delay); */ - -/* - printf ("libmpeg2: sequence extension+5 : %08x (%d)\n", - buffer[5], buffer[5] % 0x80); - */ - - picture->frame_rate_ext_n = buffer[5] & 0x31; - picture->frame_rate_ext_d = (buffer[5] >> 2) & 0x03; - - /* MPEG1 - for testing only */ - picture->mpeg1 = 0; - - return 0; -} - -static int quant_matrix_extension (picture_t * picture, uint8_t * buffer) -{ - int i; - - if (buffer[0] & 8) { - for (i = 0; i < 64; i++) - picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = - (buffer[i] << 5) | (buffer[i+1] >> 3); - buffer += 64; - } - - if (buffer[0] & 4) - for (i = 0; i < 64; i++) - picture->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = - (buffer[i] << 6) | (buffer[i+1] >> 2); - - return 0; -} - -static int picture_coding_extension (picture_t * picture, uint8_t * buffer) -{ - /* pre subtract 1 for use later in compute_motion_vector */ - picture->f_motion.f_code[0] = (buffer[0] & 15) - 1; - picture->f_motion.f_code[1] = (buffer[1] >> 4) - 1; - picture->b_motion.f_code[0] = (buffer[1] & 15) - 1; - picture->b_motion.f_code[1] = (buffer[2] >> 4) - 1; - - picture->intra_dc_precision = (buffer[2] >> 2) & 3; - picture->picture_structure = buffer[2] & 3; - picture->frame_pred_frame_dct = (buffer[3] >> 6) & 1; - picture->concealment_motion_vectors = (buffer[3] >> 5) & 1; - picture->q_scale_type = (buffer[3] >> 4) & 1; - picture->intra_vlc_format = (buffer[3] >> 3) & 1; - - if (buffer[3] & 4) /* alternate_scan */ - picture->scan = mpeg2_scan_alt; - else - picture->scan = mpeg2_scan_norm; - - /* these are not used by the decoder */ - picture->top_field_first = buffer[3] >> 7; - picture->repeat_first_field = (buffer[3] >> 1) & 1; - picture->progressive_frame = buffer[4] >> 7; - - return 0; -} - -static int sequence_display_extension (picture_t * picture, uint8_t * buffer) { - /* FIXME: implement. */ - uint32_t bit_position; - uint32_t padding; - - bit_position = 0; - padding = get_bits(buffer, 4, &bit_position); - picture->video_format = get_bits(buffer, 3, &bit_position); - picture->colour_description = get_bits(buffer, 1, &bit_position); - if(picture->colour_description) { - picture->colour_primatives = get_bits(buffer, 8, &bit_position); - picture->transfer_characteristics = get_bits(buffer, 8, &bit_position); - picture->matrix_coefficients = get_bits(buffer, 8, &bit_position); - } - picture->display_horizontal_size = get_bits(buffer, 14, &bit_position); - padding = get_bits(buffer, 1, &bit_position); - picture->display_vertical_size = get_bits(buffer, 14, &bit_position); - -#ifdef LOG_PAN_SCAN - printf("Sequence_display_extension\n"); - printf(" video_format: %u\n", picture->video_format); - printf(" colour_description: %u\n", picture->colour_description); - if(picture->colour_description) { - printf(" colour_primatives: %u\n", picture->colour_primatives); - printf(" transfer_characteristics %u\n", picture->transfer_characteristics); - printf(" matrix_coefficients %u\n", picture->matrix_coefficients); - } - printf(" display_horizontal_size %u\n", picture->display_horizontal_size); - printf(" display_vertical_size %u\n", picture->display_vertical_size); -#endif - - return 0; -} - -static int picture_display_extension (picture_t * picture, uint8_t * buffer) { - uint32_t bit_position; - uint32_t padding; - -#ifdef LOG_PAN_SCAN - printf ("libmpeg2: picture_display_extension\n"); -#endif - - bit_position = 0; - padding = get_bits(buffer, 4, &bit_position); - picture->frame_centre_horizontal_offset = get_bits(buffer, 16, &bit_position); - padding = get_bits(buffer, 1, &bit_position); - picture->frame_centre_vertical_offset = get_bits(buffer, 16, &bit_position); - padding = get_bits(buffer, 1, &bit_position); - -#ifdef LOG_PAN_SCAN - printf("Pan & Scan centre (x,y) = (%u, %u)\n", - picture->frame_centre_horizontal_offset, - picture->frame_centre_vertical_offset); -#endif - - return 0; -} - -int mpeg2_header_extension (picture_t * picture, uint8_t * buffer) -{ - switch (buffer[0] & 0xf0) { - case 0x00: /* reserved */ - return 0; - - case 0x10: /* sequence extension */ - return sequence_extension (picture, buffer); - - case 0x20: /* sequence display extension for Pan & Scan */ - return sequence_display_extension (picture, buffer); - - case 0x30: /* quant matrix extension */ - return quant_matrix_extension (picture, buffer); - - case 0x40: /* copyright extension */ - return 0; - - case 0x50: /* sequence scalable extension */ - return 0; - - case 0x60: /* reserved */ - return 0; - - case 0x70: /* picture display extension for Pan & Scan */ - return picture_display_extension (picture, buffer); - - case 0x80: /* picture coding extension */ - return picture_coding_extension (picture, buffer); - - case 0x90: /* picture spacial scalable extension */ - return 0; - - case 0xA0: /* picture temporal scalable extension */ - return 0; - - case 0xB0: /* camera parameters extension */ - return 0; - - case 0xC0: /* ITU-T extension */ - return 0; - - case 0xD0: /* reserved */ - return 0; - - case 0xE0: /* reserved */ - return 0; - - case 0xF0: /* reserved */ - return 0; - } - - return 0; -} - -int mpeg2_header_group_of_pictures (picture_t * picture, uint8_t * buffer) { - uint32_t bit_position; - uint32_t padding; - bit_position = 0; - - picture->drop_frame_flag = get_bits(buffer, 1, &bit_position); - picture->time_code_hours = get_bits(buffer, 5, &bit_position); - picture->time_code_minutes = get_bits(buffer, 6, &bit_position); - padding = get_bits(buffer, 1, &bit_position); - picture->time_code_seconds = get_bits(buffer, 6, &bit_position); - picture->time_code_pictures = get_bits(buffer, 6, &bit_position); - picture->closed_gop = get_bits(buffer, 1, &bit_position); - picture->broken_link = get_bits(buffer, 1, &bit_position); - -#ifdef LOG_PAN_SCAN - printf("Group of pictures\n"); - printf(" drop_frame_flag: %u\n", picture->drop_frame_flag); - printf(" time_code: HH:MM:SS:Pictures %02u:%02u:%02u:%02u\n", - picture->time_code_hours, - picture->time_code_minutes, - picture->time_code_seconds, - picture->time_code_pictures); - printf(" closed_gop: %u\n", picture->closed_gop); - printf(" bloken_link: %u\n", picture->broken_link); -#endif - - return 0; -} - -int mpeg2_header_picture (picture_t * picture, uint8_t * buffer) -{ - picture->picture_coding_type = (buffer [1] >> 3) & 7; - picture->vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) | - (buffer[3] >> 3)) & 0xffff; - - /* forward_f_code and backward_f_code - used in mpeg1 only */ - picture->f_motion.f_code[1] = (buffer[3] >> 2) & 1; - picture->f_motion.f_code[0] = - (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; - picture->b_motion.f_code[1] = (buffer[4] >> 6) & 1; - picture->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; - - /* move in header_process_picture_header */ - picture->second_field = - (picture->picture_structure != FRAME_PICTURE) && - !(picture->second_field); - - return 0; -} diff --git a/src/libmpeg2/idct.c b/src/libmpeg2/idct.c deleted file mode 100644 index 9f216db58..000000000 --- a/src/libmpeg2/idct.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * idct.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * Portions of this code are from the MPEG software simulation group - * idct implementation. This code will be replaced with a new - * implementation soon. - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -/**********************************************************/ -/* inverse two dimensional DCT, Chen-Wang algorithm */ -/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ -/* 32-bit integer arithmetic (8 bit coefficients) */ -/* 11 mults, 29 adds per DCT */ -/* sE, 18.8.91 */ -/**********************************************************/ -/* coefficients extended to 12 bit for IEEE1180-1990 */ -/* compliance sE, 2.1.94 */ -/**********************************************************/ - -/* this code assumes >> to be a two's-complement arithmetic */ -/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ - -#include "config.h" - -#include -#include -#include - -#include "mpeg2_internal.h" -#include - -#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ -#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ -#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ -#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ -#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ -#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ - -/* idct main entry points */ -void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); -void (* mpeg2_idct_add) (int16_t * block, uint8_t * dest, int stride); -void (* mpeg2_idct) (int16_t * block); -void (* mpeg2_zero_block) (int16_t * block); - -static uint8_t clip_lut[1024]; -#define CLIP(i) ((clip_lut+384)[ (i)]) - -/* row (horizontal) IDCT - * - * 7 pi 1 - * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l ) - * l=0 8 2 - * - * where: c[0] = 128 - * c[1..7] = 128*sqrt (2) - */ - -static void inline idct_row (int16_t * block) -{ - int x0, x1, x2, x3, x4, x5, x6, x7, x8; - - x1 = block[4] << 11; - x2 = block[6]; - x3 = block[2]; - x4 = block[1]; - x5 = block[7]; - x6 = block[5]; - x7 = block[3]; - - /* shortcut */ - if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { - block[0] = block[1] = block[2] = block[3] = block[4] = - block[5] = block[6] = block[7] = block[0]<<3; - return; - } - - x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */ - - /* first stage */ - x8 = W7 * (x4 + x5); - x4 = x8 + (W1 - W7) * x4; - x5 = x8 - (W1 + W7) * x5; - x8 = W3 * (x6 + x7); - x6 = x8 - (W3 - W5) * x6; - x7 = x8 - (W3 + W5) * x7; - - /* second stage */ - x8 = x0 + x1; - x0 -= x1; - x1 = W6 * (x3 + x2); - x2 = x1 - (W2 + W6) * x2; - x3 = x1 + (W2 - W6) * x3; - x1 = x4 + x6; - x4 -= x6; - x6 = x5 + x7; - x5 -= x7; - - /* third stage */ - x7 = x8 + x3; - x8 -= x3; - x3 = x0 + x2; - x0 -= x2; - x2 = (181 * (x4 + x5) + 128) >> 8; - x4 = (181 * (x4 - x5) + 128) >> 8; - - /* fourth stage */ - block[0] = (x7 + x1) >> 8; - block[1] = (x3 + x2) >> 8; - block[2] = (x0 + x4) >> 8; - block[3] = (x8 + x6) >> 8; - block[4] = (x8 - x6) >> 8; - block[5] = (x0 - x4) >> 8; - block[6] = (x3 - x2) >> 8; - block[7] = (x7 - x1) >> 8; -} - -/* column (vertical) IDCT - * - * 7 pi 1 - * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l ) - * l=0 8 2 - * - * where: c[0] = 1/1024 - * c[1..7] = (1/1024)*sqrt (2) - */ - -static void inline idct_col (int16_t *block) -{ - int x0, x1, x2, x3, x4, x5, x6, x7, x8; - - /* shortcut */ - x1 = block [8*4] << 8; - x2 = block [8*6]; - x3 = block [8*2]; - x4 = block [8*1]; - x5 = block [8*7]; - x6 = block [8*5]; - x7 = block [8*3]; - -#if 0 - if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { - block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] = - block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6; - return; - } -#endif - - x0 = (block[8*0] << 8) + 8192; - - /* first stage */ - x8 = W7 * (x4 + x5) + 4; - x4 = (x8 + (W1 - W7) * x4) >> 3; - x5 = (x8 - (W1 + W7) * x5) >> 3; - x8 = W3 * (x6 + x7) + 4; - x6 = (x8 - (W3 - W5) * x6) >> 3; - x7 = (x8 - (W3 + W5) * x7) >> 3; - - /* second stage */ - x8 = x0 + x1; - x0 -= x1; - x1 = W6 * (x3 + x2) + 4; - x2 = (x1 - (W2 + W6) * x2) >> 3; - x3 = (x1 + (W2 - W6) * x3) >> 3; - x1 = x4 + x6; - x4 -= x6; - x6 = x5 + x7; - x5 -= x7; - - /* third stage */ - x7 = x8 + x3; - x8 -= x3; - x3 = x0 + x2; - x0 -= x2; - x2 = (181 * (x4 + x5) + 128) >> 8; - x4 = (181 * (x4 - x5) + 128) >> 8; - - /* fourth stage */ - block[8*0] = (x7 + x1) >> 14; - block[8*1] = (x3 + x2) >> 14; - block[8*2] = (x0 + x4) >> 14; - block[8*3] = (x8 + x6) >> 14; - block[8*4] = (x8 - x6) >> 14; - block[8*5] = (x0 - x4) >> 14; - block[8*6] = (x3 - x2) >> 14; - block[8*7] = (x7 - x1) >> 14; -} - -static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest, int stride) -{ - int i; - - for (i = 0; i < 8; i++) - idct_row (block + 8 * i); - - for (i = 0; i < 8; i++) - idct_col (block + i); - - i = 8; - do { - dest[0] = CLIP (block[0]); - dest[1] = CLIP (block[1]); - dest[2] = CLIP (block[2]); - dest[3] = CLIP (block[3]); - dest[4] = CLIP (block[4]); - dest[5] = CLIP (block[5]); - dest[6] = CLIP (block[6]); - dest[7] = CLIP (block[7]); - - block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; - block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; - - dest += stride; - block += 8; - } while (--i); -} - -static void mpeg2_idct_add_c (int16_t * block, uint8_t * dest, int stride) -{ - int i; - - for (i = 0; i < 8; i++) - idct_row (block + 8 * i); - - for (i = 0; i < 8; i++) - idct_col (block + i); - - i = 8; - do { - dest[0] = CLIP (block[0] + dest[0]); - dest[1] = CLIP (block[1] + dest[1]); - dest[2] = CLIP (block[2] + dest[2]); - dest[3] = CLIP (block[3] + dest[3]); - dest[4] = CLIP (block[4] + dest[4]); - dest[5] = CLIP (block[5] + dest[5]); - dest[6] = CLIP (block[6] + dest[6]); - dest[7] = CLIP (block[7] + dest[7]); - - block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; - block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; - - dest += stride; - block += 8; - } while (--i); -} - -static void mpeg2_idct_c (int16_t * block) -{ - int i; - - for (i = 0; i < 8; i++) - idct_row (block + 8 * i); - - for (i = 0; i < 8; i++) - idct_col (block + i); -} - -static void mpeg2_zero_block_c (int16_t * wblock) -{ - memset( wblock, 0, sizeof(int16_t) * 64 ); -} - -void mpeg2_idct_init (uint32_t mm_accel) -{ - mpeg2_zero_block = mpeg2_zero_block_c; - -#if defined(ARCH_X86) || defined(ARCH_X86_64) - if (mm_accel & MM_ACCEL_X86_MMXEXT) { -#ifdef LOG - fprintf (stderr, "Using MMXEXT for IDCT transform\n"); -#endif - mpeg2_idct_copy = mpeg2_idct_copy_mmxext; - mpeg2_idct_add = mpeg2_idct_add_mmxext; - mpeg2_idct = mpeg2_idct_mmxext; - mpeg2_zero_block = mpeg2_zero_block_mmx; - mpeg2_idct_mmx_init (); - } else if (mm_accel & MM_ACCEL_X86_MMX) { -#ifdef LOG - fprintf (stderr, "Using MMX for IDCT transform\n"); -#endif - mpeg2_idct_copy = mpeg2_idct_copy_mmx; - mpeg2_idct_add = mpeg2_idct_add_mmx; - mpeg2_idct = mpeg2_idct_mmx; - mpeg2_zero_block = mpeg2_zero_block_mmx; - mpeg2_idct_mmx_init (); - } else -#endif -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) - if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { -#ifdef LOG - fprintf (stderr, "Using altivec for IDCT transform\n"); -#endif - mpeg2_idct_copy = mpeg2_idct_copy_altivec; - mpeg2_idct_add = mpeg2_idct_add_altivec; - mpeg2_idct_altivec_init (); - mpeg2_idct = mpeg2_idct_c; - } else -#endif -#ifdef LIBMPEG2_MLIB - if (mm_accel & MM_ACCEL_MLIB) { - char * env_var; - - env_var = getenv ("MLIB_NON_IEEE"); - - mpeg2_idct = mpeg2_idct_mlib; - if (env_var == NULL) { -#ifdef LOG - fprintf (stderr, "Using mlib for IDCT transform\n"); -#endif - mpeg2_idct_add = mpeg2_idct_add_mlib; - } else { - fprintf (stderr, "Using non-IEEE mlib for IDCT transform\n"); - mpeg2_idct_add = mpeg2_idct_add_mlib_non_ieee; - } - mpeg2_idct_copy = mpeg2_idct_copy_mlib_non_ieee; - } else -#endif - { - int i; - -#ifdef LOG - fprintf (stderr, "No accelerated IDCT transform found\n"); -#endif - mpeg2_idct_copy = mpeg2_idct_copy_c; - mpeg2_idct_add = mpeg2_idct_add_c; - mpeg2_idct = mpeg2_idct_c; - for (i = -384; i < 640; i++) - clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i); - } -} diff --git a/src/libmpeg2/idct_altivec.c b/src/libmpeg2/idct_altivec.c deleted file mode 100644 index de396560b..000000000 --- a/src/libmpeg2/idct_altivec.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * idct_altivec.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) - -#include - -#include - -#include "mpeg2_internal.h" -#include - -#define vector_s16_t vector signed short -#define vector_u16_t vector unsigned short -#define vector_s8_t vector signed char -#define vector_u8_t vector unsigned char -#define vector_s32_t vector signed int -#define vector_u32_t vector unsigned int - -#define IDCT_HALF \ - /* 1st stage */ \ - t1 = vec_mradds (a1, vx7, vx1 ); \ - t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7)); \ - t7 = vec_mradds (a2, vx5, vx3); \ - t3 = vec_mradds (ma2, vx3, vx5); \ - \ - /* 2nd stage */ \ - t5 = vec_adds (vx0, vx4); \ - t0 = vec_subs (vx0, vx4); \ - t2 = vec_mradds (a0, vx6, vx2); \ - t4 = vec_mradds (a0, vx2, vec_subs (zero,vx6)); \ - t6 = vec_adds (t8, t3); \ - t3 = vec_subs (t8, t3); \ - t8 = vec_subs (t1, t7); \ - t1 = vec_adds (t1, t7); \ - \ - /* 3rd stage */ \ - t7 = vec_adds (t5, t2); \ - t2 = vec_subs (t5, t2); \ - t5 = vec_adds (t0, t4); \ - t0 = vec_subs (t0, t4); \ - t4 = vec_subs (t8, t3); \ - t3 = vec_adds (t8, t3); \ - \ - /* 4th stage */ \ - vy0 = vec_adds (t7, t1); \ - vy7 = vec_subs (t7, t1); \ - vy1 = vec_mradds (c4, t3, t5); \ - vy6 = vec_mradds (mc4, t3, t5); \ - vy2 = vec_mradds (c4, t4, t0); \ - vy5 = vec_mradds (mc4, t4, t0); \ - vy3 = vec_adds (t2, t6); \ - vy4 = vec_subs (t2, t6); - -#define IDCT \ - vector_s16_t vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7; \ - vector_s16_t vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7; \ - vector_s16_t a0, a1, a2, ma2, c4, mc4, zero, bias; \ - vector_s16_t t0, t1, t2, t3, t4, t5, t6, t7, t8; \ - vector_u16_t shift; \ - \ - c4 = vec_splat (constants[0], 0); \ - a0 = vec_splat (constants[0], 1); \ - a1 = vec_splat (constants[0], 2); \ - a2 = vec_splat (constants[0], 3); \ - mc4 = vec_splat (constants[0], 4); \ - ma2 = vec_splat (constants[0], 5); \ - bias = (vector_s16_t)vec_splat ((vector_s32_t)constants[0], 3); \ - \ - zero = vec_splat_s16 (0); \ - shift = vec_splat_u16 (4); \ - \ - vx0 = vec_mradds (vec_sl (block[0], shift), constants[1], zero); \ - vx1 = vec_mradds (vec_sl (block[1], shift), constants[2], zero); \ - vx2 = vec_mradds (vec_sl (block[2], shift), constants[3], zero); \ - vx3 = vec_mradds (vec_sl (block[3], shift), constants[4], zero); \ - vx4 = vec_mradds (vec_sl (block[4], shift), constants[1], zero); \ - vx5 = vec_mradds (vec_sl (block[5], shift), constants[4], zero); \ - vx6 = vec_mradds (vec_sl (block[6], shift), constants[3], zero); \ - vx7 = vec_mradds (vec_sl (block[7], shift), constants[2], zero); \ - \ - IDCT_HALF \ - \ - vx0 = vec_mergeh (vy0, vy4); \ - vx1 = vec_mergel (vy0, vy4); \ - vx2 = vec_mergeh (vy1, vy5); \ - vx3 = vec_mergel (vy1, vy5); \ - vx4 = vec_mergeh (vy2, vy6); \ - vx5 = vec_mergel (vy2, vy6); \ - vx6 = vec_mergeh (vy3, vy7); \ - vx7 = vec_mergel (vy3, vy7); \ - \ - vy0 = vec_mergeh (vx0, vx4); \ - vy1 = vec_mergel (vx0, vx4); \ - vy2 = vec_mergeh (vx1, vx5); \ - vy3 = vec_mergel (vx1, vx5); \ - vy4 = vec_mergeh (vx2, vx6); \ - vy5 = vec_mergel (vx2, vx6); \ - vy6 = vec_mergeh (vx3, vx7); \ - vy7 = vec_mergel (vx3, vx7); \ - \ - vx0 = vec_adds (vec_mergeh (vy0, vy4), bias); \ - vx1 = vec_mergel (vy0, vy4); \ - vx2 = vec_mergeh (vy1, vy5); \ - vx3 = vec_mergel (vy1, vy5); \ - vx4 = vec_mergeh (vy2, vy6); \ - vx5 = vec_mergel (vy2, vy6); \ - vx6 = vec_mergeh (vy3, vy7); \ - vx7 = vec_mergel (vy3, vy7); \ - \ - IDCT_HALF \ - \ - shift = vec_splat_u16 (6); \ - vx0 = vec_sra (vy0, shift); \ - vx1 = vec_sra (vy1, shift); \ - vx2 = vec_sra (vy2, shift); \ - vx3 = vec_sra (vy3, shift); \ - vx4 = vec_sra (vy4, shift); \ - vx5 = vec_sra (vy5, shift); \ - vx6 = vec_sra (vy6, shift); \ - vx7 = vec_sra (vy7, shift); - -#if defined( __APPLE_CC__ ) && defined( __APPLE_ALTIVEC__ ) /* apple */ -#define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) (a, b, c, d, e, f, g, h) -#else /* gnu */ -#define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) {a, b, c, d, e, f, g, h} -#endif - -static vector_s16_t constants[5] = { - VEC_S16(23170, 13573, 6518, 21895, -23170, -21895, 32, 31), - VEC_S16(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725), - VEC_S16(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521), - VEC_S16(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692), - VEC_S16(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722) -}; - -void mpeg2_idct_copy_altivec (vector_s16_t * block, unsigned char * dest, - int stride) -{ - vector_u8_t tmp; - - IDCT - -#define COPY(dest,src) \ - tmp = vec_packsu (src, src); \ - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - - COPY (dest, vx0) dest += stride; - COPY (dest, vx1) dest += stride; - COPY (dest, vx2) dest += stride; - COPY (dest, vx3) dest += stride; - COPY (dest, vx4) dest += stride; - COPY (dest, vx5) dest += stride; - COPY (dest, vx6) dest += stride; - COPY (dest, vx7) - memset (block, 0, 64 * sizeof (signed short)); -} - -void mpeg2_idct_add_altivec (vector_s16_t * block, unsigned char * dest, - int stride) -{ - vector_u8_t tmp; - vector_s16_t tmp2, tmp3; - vector_u8_t perm0; - vector_u8_t perm1; - vector_u8_t p0, p1, p; - - IDCT - - p0 = vec_lvsl (0, dest); - p1 = vec_lvsl (stride, dest); - p = vec_splat_u8 (-1); - perm0 = vec_mergeh (p, p0); - perm1 = vec_mergeh (p, p1); - -#define ADD(dest,src,perm) \ - /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ - tmp = vec_ld (0, dest); \ - tmp2 = (vector_s16_t)vec_perm (tmp, (vector_u8_t)zero, perm); \ - tmp3 = vec_adds (tmp2, src); \ - tmp = vec_packsu (tmp3, tmp3); \ - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - - ADD (dest, vx0, perm0) dest += stride; - ADD (dest, vx1, perm1) dest += stride; - ADD (dest, vx2, perm0) dest += stride; - ADD (dest, vx3, perm1) dest += stride; - ADD (dest, vx4, perm0) dest += stride; - ADD (dest, vx5, perm1) dest += stride; - ADD (dest, vx6, perm0) dest += stride; - ADD (dest, vx7, perm1) - memset (block, 0, 64 * sizeof (signed short)); -} - -void mpeg2_idct_altivec_init (void) -{ - int i, j; - - /* the altivec idct uses a transposed input, so we patch scan tables */ - for (i = 0; i < 64; i++) { - j = mpeg2_scan_norm[i]; - mpeg2_scan_norm[i] = (j >> 3) | ((j & 7) << 3); - j = mpeg2_scan_alt[i]; - mpeg2_scan_alt[i] = (j >> 3) | ((j & 7) << 3); - } -} - -#endif /* ARCH_PPC && ENABLED_ALTIVEC */ - diff --git a/src/libmpeg2/idct_mlib.c b/src/libmpeg2/idct_mlib.c deleted file mode 100644 index e573c9790..000000000 --- a/src/libmpeg2/idct_mlib.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * idct_mlib.c - * Copyright (C) 1999-2002 Håkan Hjort - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#ifdef LIBMPEG2_MLIB - -#include -#include -#include -#include -#include -#include - -#include "mpeg2_internal.h" - -void mpeg2_idct_add_mlib (int16_t * block, uint8_t * dest, int stride) -{ - mlib_VideoIDCT_IEEE_S16_S16 (block, block); - mlib_VideoAddBlock_U8_S16 (dest, block, stride); - memset (block, 0, 64 * sizeof (uint16_t)); -} - -void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, - int stride) -{ - mlib_VideoIDCT8x8_U8_S16 (dest, block, stride); - memset (block, 0, 64 * sizeof (uint16_t)); -} - -void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, int stride) -{ - mlib_VideoIDCT8x8_S16_S16 (block, block); - mlib_VideoAddBlock_U8_S16 (dest, block, stride); - memset (block, 0, 64 * sizeof (uint16_t)); -} - -void mpeg2_idct_mlib (int16_t * block) -{ - mlib_VideoIDCT_IEEE_S16_S16 (block, block); -} - -#endif diff --git a/src/libmpeg2/idct_mlib.h b/src/libmpeg2/idct_mlib.h deleted file mode 100644 index 1fb0787dd..000000000 --- a/src/libmpeg2/idct_mlib.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * idct_mlib.h - * - * Copyright (C) 1999, Håkan Hjort - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec 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, or (at your option) - * any later version. - * - * mpeg2dec 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, - * - */ - -void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride); -void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride); diff --git a/src/libmpeg2/idct_mmx.c b/src/libmpeg2/idct_mmx.c deleted file mode 100644 index 6bb4bfbf0..000000000 --- a/src/libmpeg2/idct_mmx.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * idct_mmx.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#if defined(ARCH_X86) || defined(ARCH_X86_64) - -#include - -#include "mpeg2_internal.h" -#include - -#define ROW_SHIFT 11 -#define COL_SHIFT 6 - -#define round(bias) ((int)(((bias)+0.5) * (1<> ROW_SHIFT; - row[1] = (a1 + b1) >> ROW_SHIFT; - row[2] = (a2 + b2) >> ROW_SHIFT; - row[3] = (a3 + b3) >> ROW_SHIFT; - row[4] = (a3 - b3) >> ROW_SHIFT; - row[5] = (a2 - b2) >> ROW_SHIFT; - row[6] = (a1 - b1) >> ROW_SHIFT; - row[7] = (a0 - b0) >> ROW_SHIFT; -} -#endif - - -/* MMXEXT row IDCT */ - -#define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \ - c4, c6, c4, c6, \ - c1, c3, -c1, -c5, \ - c5, c7, c3, -c7, \ - c4, -c6, c4, -c6, \ - -c4, c2, c4, -c2, \ - c5, -c1, c3, -c1, \ - c7, c3, c7, -c5 } - -static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table) -{ - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 - - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 - - movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 - - movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 - pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 - - pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 -} - -static inline void mmxext_row (int16_t * table, int32_t * rounder) -{ - movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1 - pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6 - - pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2 - pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5 - - movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5 - pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 - - paddd_m2r (*rounder, mm3); // mm3 += rounder - pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7 - - pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 - paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder - - pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3 - movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder - - pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7 - paddd_r2r (mm7, mm1); // mm1 = b1 b0 - - paddd_m2r (*rounder, mm0); // mm0 += rounder - psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder - - psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 - paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder - - paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder - psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 - - paddd_r2r (mm6, mm5); // mm5 = b3 b2 - movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder - - paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder - psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder -} - -static inline void mmxext_row_tail (int16_t * row, int store) -{ - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 - - psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 - - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 - - packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 - - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 - - /* slot */ - - movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 -} - -static inline void mmxext_row_mid (int16_t * row, int store, - int offset, int16_t * table) -{ - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 - - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 - - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 - - packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 - - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 - - movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 - movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 - - pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 - - movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 - pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 -} - - -/* MMX row IDCT */ - -#define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \ - c4, c6, -c4, -c2, \ - c1, c3, c3, -c7, \ - c5, c7, -c1, -c5, \ - c4, -c6, c4, -c2, \ - -c4, c2, c4, -c6, \ - c5, -c1, c7, -c5, \ - c7, c3, c3, -c1 } - -static inline void mmx_row_head (int16_t * row, int offset, int16_t * table) -{ - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 - - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 - - movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 - - punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 - - movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 - pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 - - movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 - punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 -} - -static inline void mmx_row (int16_t * table, int32_t * rounder) -{ - pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 - punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1 - - pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2 - punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5 - - movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5 - pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3 - - paddd_m2r (*rounder, mm3); // mm3 += rounder - pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 - - pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 - paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder - - pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3 - movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder - - pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7 - paddd_r2r (mm7, mm1); // mm1 = b1 b0 - - paddd_m2r (*rounder, mm0); // mm0 += rounder - psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder - - psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 - paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder - - paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder - psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 - - paddd_r2r (mm6, mm5); // mm5 = b3 b2 - movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder - - paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder - psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder -} - -static inline void mmx_row_tail (int16_t * row, int store) -{ - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 - - psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 - - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 - - packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 - - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5 - - pslld_i2r (16, mm7); // mm7 = y7 0 y5 0 - - psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4 - - por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4 - - /* slot */ - - movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 -} - -static inline void mmx_row_mid (int16_t * row, int store, - int offset, int16_t * table) -{ - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 - - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 - - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 - - packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 - - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5 - - punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 - psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4 - - movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 - pslld_i2r (16, mm1); // mm1 = y7 0 y5 0 - - movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 - por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4 - - movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 - punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 - - movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 - pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 -} - - -#if 0 -// C column IDCT - its just here to document the MMXEXT and MMX versions -static inline void idct_col (int16_t * col, int offset) -{ -/* multiplication - as implemented on mmx */ -#define F(c,x) (((c) * (x)) >> 16) - -/* saturation - it helps us handle torture test cases */ -#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x)) - - int16_t x0, x1, x2, x3, x4, x5, x6, x7; - int16_t y0, y1, y2, y3, y4, y5, y6, y7; - int16_t a0, a1, a2, a3, b0, b1, b2, b3; - int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12; - - col += offset; - - x0 = col[0*8]; - x1 = col[1*8]; - x2 = col[2*8]; - x3 = col[3*8]; - x4 = col[4*8]; - x5 = col[5*8]; - x6 = col[6*8]; - x7 = col[7*8]; - - u04 = S (x0 + x4); - v04 = S (x0 - x4); - u26 = S (F (T2, x6) + x2); - v26 = S (F (T2, x2) - x6); - - a0 = S (u04 + u26); - a1 = S (v04 + v26); - a2 = S (v04 - v26); - a3 = S (u04 - u26); - - u17 = S (F (T1, x7) + x1); - v17 = S (F (T1, x1) - x7); - u35 = S (F (T3, x5) + x3); - v35 = S (F (T3, x3) - x5); - - b0 = S (u17 + u35); - b3 = S (v17 - v35); - u12 = S (u17 - u35); - v12 = S (v17 + v35); - u12 = S (2 * F (C4, u12)); - v12 = S (2 * F (C4, v12)); - b1 = S (u12 + v12); - b2 = S (u12 - v12); - - y0 = S (a0 + b0) >> COL_SHIFT; - y1 = S (a1 + b1) >> COL_SHIFT; - y2 = S (a2 + b2) >> COL_SHIFT; - y3 = S (a3 + b3) >> COL_SHIFT; - - y4 = S (a3 - b3) >> COL_SHIFT; - y5 = S (a2 - b2) >> COL_SHIFT; - y6 = S (a1 - b1) >> COL_SHIFT; - y7 = S (a0 - b0) >> COL_SHIFT; - - col[0*8] = y0; - col[1*8] = y1; - col[2*8] = y2; - col[3*8] = y3; - col[4*8] = y4; - col[5*8] = y5; - col[6*8] = y6; - col[7*8] = y7; -} -#endif - - -// MMX column IDCT -static inline void idct_col (int16_t * col, int offset) -{ -#define T1 13036 -#define T2 27146 -#define T3 43790 -#define C4 23170 - - static short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; - static short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; - static short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; - static short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; - - /* column code adapted from peter gubanov */ - /* http://www.elecard.com/peter/idct.shtml */ - - movq_m2r (*_T1, mm0); // mm0 = T1 - - movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1 - movq_r2r (mm0, mm2); // mm2 = T1 - - movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7 - pmulhw_r2r (mm1, mm0); // mm0 = T1*x1 - - movq_m2r (*_T3, mm5); // mm5 = T3 - pmulhw_r2r (mm4, mm2); // mm2 = T1*x7 - - movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5 - movq_r2r (mm5, mm7); // mm7 = T3-1 - - movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3 - psubsw_r2r (mm4, mm0); // mm0 = v17 - - movq_m2r (*_T2, mm4); // mm4 = T2 - pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3 - - paddsw_r2r (mm2, mm1); // mm1 = u17 - pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5 - - /* slot */ - - movq_r2r (mm4, mm2); // mm2 = T2 - paddsw_r2r (mm3, mm5); // mm5 = T3*x3 - - pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2 - paddsw_r2r (mm6, mm7); // mm7 = T3*x5 - - psubsw_r2r (mm6, mm5); // mm5 = v35 - paddsw_r2r (mm3, mm7); // mm7 = u35 - - movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6 - movq_r2r (mm0, mm6); // mm6 = v17 - - pmulhw_r2r (mm3, mm2); // mm2 = T2*x6 - psubsw_r2r (mm5, mm0); // mm0 = b3 - - psubsw_r2r (mm3, mm4); // mm4 = v26 - paddsw_r2r (mm6, mm5); // mm5 = v12 - - movq_r2m (mm0, *(col+offset+3*8)); // save b3 in scratch0 - movq_r2r (mm1, mm6); // mm6 = u17 - - paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26 - paddsw_r2r (mm7, mm6); // mm6 = b0 - - psubsw_r2r (mm7, mm1); // mm1 = u12 - movq_r2r (mm1, mm7); // mm7 = u12 - - movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0 - paddsw_r2r (mm5, mm1); // mm1 = u12+v12 - - movq_m2r (*_C4, mm0); // mm0 = C4/2 - psubsw_r2r (mm5, mm7); // mm7 = u12-v12 - - movq_r2m (mm6, *(col+offset+5*8)); // save b0 in scratch1 - pmulhw_r2r (mm0, mm1); // mm1 = b1/2 - - movq_r2r (mm4, mm6); // mm6 = v26 - pmulhw_r2r (mm0, mm7); // mm7 = b2/2 - - movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4 - movq_r2r (mm3, mm0); // mm0 = x0 - - psubsw_r2r (mm5, mm3); // mm3 = v04 - paddsw_r2r (mm5, mm0); // mm0 = u04 - - paddsw_r2r (mm3, mm4); // mm4 = a1 - movq_r2r (mm0, mm5); // mm5 = u04 - - psubsw_r2r (mm6, mm3); // mm3 = a2 - paddsw_r2r (mm2, mm5); // mm5 = a0 - - paddsw_r2r (mm1, mm1); // mm1 = b1 - psubsw_r2r (mm2, mm0); // mm0 = a3 - - paddsw_r2r (mm7, mm7); // mm7 = b2 - movq_r2r (mm3, mm2); // mm2 = a2 - - movq_r2r (mm4, mm6); // mm6 = a1 - paddsw_r2r (mm7, mm3); // mm3 = a2+b2 - - psraw_i2r (COL_SHIFT, mm3); // mm3 = y2 - paddsw_r2r (mm1, mm4); // mm4 = a1+b1 - - psraw_i2r (COL_SHIFT, mm4); // mm4 = y1 - psubsw_r2r (mm1, mm6); // mm6 = a1-b1 - - movq_m2r (*(col+offset+5*8), mm1); // mm1 = b0 - psubsw_r2r (mm7, mm2); // mm2 = a2-b2 - - psraw_i2r (COL_SHIFT, mm6); // mm6 = y6 - movq_r2r (mm5, mm7); // mm7 = a0 - - movq_r2m (mm4, *(col+offset+1*8)); // save y1 - psraw_i2r (COL_SHIFT, mm2); // mm2 = y5 - - movq_r2m (mm3, *(col+offset+2*8)); // save y2 - paddsw_r2r (mm1, mm5); // mm5 = a0+b0 - - movq_m2r (*(col+offset+3*8), mm4); // mm4 = b3 - psubsw_r2r (mm1, mm7); // mm7 = a0-b0 - - psraw_i2r (COL_SHIFT, mm5); // mm5 = y0 - movq_r2r (mm0, mm3); // mm3 = a3 - - movq_r2m (mm2, *(col+offset+5*8)); // save y5 - psubsw_r2r (mm4, mm3); // mm3 = a3-b3 - - psraw_i2r (COL_SHIFT, mm7); // mm7 = y7 - paddsw_r2r (mm0, mm4); // mm4 = a3+b3 - - movq_r2m (mm5, *(col+offset+0*8)); // save y0 - psraw_i2r (COL_SHIFT, mm3); // mm3 = y4 - - movq_r2m (mm6, *(col+offset+6*8)); // save y6 - psraw_i2r (COL_SHIFT, mm4); // mm4 = y3 - - movq_r2m (mm7, *(col+offset+7*8)); // save y7 - - movq_r2m (mm3, *(col+offset+4*8)); // save y4 - - movq_r2m (mm4, *(col+offset+3*8)); // save y3 -} - - -static int32_t rounder0[] ATTR_ALIGN(8) = - rounder ((1 << (COL_SHIFT - 1)) - 0.5); -static int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); -static int32_t rounder1[] ATTR_ALIGN(8) = - rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ -static int32_t rounder7[] ATTR_ALIGN(8) = - rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ -static int32_t rounder2[] ATTR_ALIGN(8) = - rounder (0.60355339059); /* C2 * (C6+C2)/2 */ -static int32_t rounder6[] ATTR_ALIGN(8) = - rounder (-0.25); /* C2 * (C6-C2)/2 */ -static int32_t rounder3[] ATTR_ALIGN(8) = - rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ -static int32_t rounder5[] ATTR_ALIGN(8) = - rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ - - -#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ -static inline void idct (int16_t * block) \ -{ \ - static int16_t table04[] ATTR_ALIGN(16) = \ - table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ - static int16_t table17[] ATTR_ALIGN(16) = \ - table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ - static int16_t table26[] ATTR_ALIGN(16) = \ - table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ - static int16_t table35[] ATTR_ALIGN(16) = \ - table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ - \ - idct_row_head (block, 0*8, table04); \ - idct_row (table04, rounder0); \ - idct_row_mid (block, 0*8, 4*8, table04); \ - idct_row (table04, rounder4); \ - idct_row_mid (block, 4*8, 1*8, table17); \ - idct_row (table17, rounder1); \ - idct_row_mid (block, 1*8, 7*8, table17); \ - idct_row (table17, rounder7); \ - idct_row_mid (block, 7*8, 2*8, table26); \ - idct_row (table26, rounder2); \ - idct_row_mid (block, 2*8, 6*8, table26); \ - idct_row (table26, rounder6); \ - idct_row_mid (block, 6*8, 3*8, table35); \ - idct_row (table35, rounder3); \ - idct_row_mid (block, 3*8, 5*8, table35); \ - idct_row (table35, rounder5); \ - idct_row_tail (block, 5*8); \ - \ - idct_col (block, 0); \ - idct_col (block, 4); \ -} - - -#define COPY_MMX(offset,r0,r1,r2) \ -do { \ - movq_m2r (*(block+offset), r0); \ - dest += stride; \ - movq_m2r (*(block+offset+4), r1); \ - movq_r2m (r2, *dest); \ - packuswb_r2r (r1, r0); \ -} while (0) - -static void block_copy (int16_t * block, uint8_t * dest, int stride) -{ - movq_m2r (*(block+0*8), mm0); - movq_m2r (*(block+0*8+4), mm1); - movq_m2r (*(block+1*8), mm2); - packuswb_r2r (mm1, mm0); - movq_m2r (*(block+1*8+4), mm3); - movq_r2m (mm0, *dest); - packuswb_r2r (mm3, mm2); - COPY_MMX (2*8, mm0, mm1, mm2); - COPY_MMX (3*8, mm2, mm3, mm0); - COPY_MMX (4*8, mm0, mm1, mm2); - COPY_MMX (5*8, mm2, mm3, mm0); - COPY_MMX (6*8, mm0, mm1, mm2); - COPY_MMX (7*8, mm2, mm3, mm0); - movq_r2m (mm2, *(dest+stride)); -} - - -#define ADD_MMX(offset,r1,r2,r3,r4) \ -do { \ - movq_m2r (*(dest+2*stride), r1); \ - packuswb_r2r (r4, r3); \ - movq_r2r (r1, r2); \ - dest += stride; \ - movq_r2m (r3, *dest); \ - punpcklbw_r2r (mm0, r1); \ - paddsw_m2r (*(block+offset), r1); \ - punpckhbw_r2r (mm0, r2); \ - paddsw_m2r (*(block+offset+4), r2); \ -} while (0) - -static void block_add (int16_t * block, uint8_t * dest, int stride) -{ - movq_m2r (*dest, mm1); - pxor_r2r (mm0, mm0); - movq_m2r (*(dest+stride), mm3); - movq_r2r (mm1, mm2); - punpcklbw_r2r (mm0, mm1); - movq_r2r (mm3, mm4); - paddsw_m2r (*(block+0*8), mm1); - punpckhbw_r2r (mm0, mm2); - paddsw_m2r (*(block+0*8+4), mm2); - punpcklbw_r2r (mm0, mm3); - paddsw_m2r (*(block+1*8), mm3); - packuswb_r2r (mm2, mm1); - punpckhbw_r2r (mm0, mm4); - movq_r2m (mm1, *dest); - paddsw_m2r (*(block+1*8+4), mm4); - ADD_MMX (2*8, mm1, mm2, mm3, mm4); - ADD_MMX (3*8, mm3, mm4, mm1, mm2); - ADD_MMX (4*8, mm1, mm2, mm3, mm4); - ADD_MMX (5*8, mm3, mm4, mm1, mm2); - ADD_MMX (6*8, mm1, mm2, mm3, mm4); - ADD_MMX (7*8, mm3, mm4, mm1, mm2); - packuswb_r2r (mm4, mm3); - movq_r2m (mm3, *(dest+stride)); -} - -static inline void block_zero (int16_t * block) { - pxor_r2r (mm0, mm0); - movq_r2m (mm0, *(block+0*4)); - movq_r2m (mm0, *(block+1*4)); - movq_r2m (mm0, *(block+2*4)); - movq_r2m (mm0, *(block+3*4)); - movq_r2m (mm0, *(block+4*4)); - movq_r2m (mm0, *(block+5*4)); - movq_r2m (mm0, *(block+6*4)); - movq_r2m (mm0, *(block+7*4)); - movq_r2m (mm0, *(block+8*4)); - movq_r2m (mm0, *(block+9*4)); - movq_r2m (mm0, *(block+10*4)); - movq_r2m (mm0, *(block+11*4)); - movq_r2m (mm0, *(block+12*4)); - movq_r2m (mm0, *(block+13*4)); - movq_r2m (mm0, *(block+14*4)); - movq_r2m (mm0, *(block+15*4)); -} - -declare_idct (mmxext_idct, mmxext_table, - mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid) - -void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride) -{ - mmxext_idct (block); - block_copy (block, dest, stride); - block_zero (block); -} - -void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int stride) -{ - mmxext_idct (block); - block_add (block, dest, stride); - block_zero (block); -} - -void mpeg2_idct_mmxext (int16_t * block) -{ - mmxext_idct (block); -} - -declare_idct (mmx_idct, mmx_table, - mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid) - -void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride) -{ - mmx_idct (block); - block_copy (block, dest, stride); - block_zero (block); -} - -void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int stride) -{ - mmx_idct (block); - block_add (block, dest, stride); - block_zero (block); -} - -void mpeg2_idct_mmx (int16_t * block) -{ - mmx_idct (block); -} - -void mpeg2_zero_block_mmx (int16_t * block) -{ - block_zero (block); -} - -void mpeg2_idct_mmx_init (void) -{ - int i, j; - - /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ - - for (i = 0; i < 64; i++) { - j = mpeg2_scan_norm[i]; - mpeg2_scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); - j = mpeg2_scan_alt[i]; - mpeg2_scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); - } -} - -#endif diff --git a/src/libmpeg2/libmpeg2_accel.c b/src/libmpeg2/libmpeg2_accel.c deleted file mode 100644 index 92c0e280b..000000000 --- a/src/libmpeg2/libmpeg2_accel.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * libmpeg2_accel.c - * Copyright (C) 2004 The Unichrome Project. - * Copyright (C) 2005 Thomas Hellstrom. - * - * 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 - */ - -#include -#include "mpeg2.h" -#include "mpeg2_internal.h" -#include "xvmc_vld.h" -#include "libmpeg2_accel.h" - - -void -libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt) -{ - xvmc_setup_scan_ptable(); -} - - -int -libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture) -{ - accel->xvmc_last_slice_code=-1; - if ( !picture->current_frame ) - return 0; - if (frame_format == XINE_IMGFMT_XXMC) { - xine_xxmc_t *xxmc = (xine_xxmc_t *) - picture->current_frame->accel_data; - switch(xxmc->acceleration) { - case XINE_XVMC_ACCEL_VLD: - case XINE_XVMC_ACCEL_IDCT: - case XINE_XVMC_ACCEL_MOCOMP: - xxmc->proc_xxmc_flush( picture->current_frame ); - break; - default: - break; - } - } - return 0; -} - -int -libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture) -{ - switch(frame_format) { - case XINE_IMGFMT_XXMC: - case XINE_IMGFMT_XVMC: { - xine_xvmc_t *xvmc = (xine_xvmc_t *) - picture->current_frame->accel_data; - picture->mc = xvmc->macroblocks; - return 0; - } - default: - break; - } - return 1; -} - -int -libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, - picture_t *picture, double ratio, uint32_t flags) -{ - if (picture->current_frame) { - if (XINE_IMGFMT_XXMC == frame_format) { - xine_xxmc_t *xxmc = (xine_xxmc_t *) - picture->current_frame->accel_data; - - /* - * Make a request for acceleration type and mpeg coding from - * the output plugin. - */ - - xxmc->fallback_format = XINE_IMGFMT_YV12; - xxmc->acceleration = XINE_XVMC_ACCEL_VLD| XINE_XVMC_ACCEL_IDCT - | XINE_XVMC_ACCEL_MOCOMP ; - - /* - * Standard MOCOMP / IDCT XvMC implementation for interlaced streams - * is buggy. The bug is inherited from the old XvMC driver. Don't use it until - * it has been fixed. (A volunteer ?) - */ - - if ( picture->picture_structure != 3 ) { - picture->top_field_first = (picture->picture_structure == 1); - xxmc->acceleration &= ~( XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP ); - } - - xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2; - xxmc->proc_xxmc_update_frame (picture->current_frame->driver, - picture->current_frame, - picture->coded_picture_width, - picture->coded_picture_height, - ratio, - XINE_IMGFMT_XXMC, flags); - } - } - return 0; -} - -void -libmpeg2_accel_frame_completion(mpeg2dec_accel_t * accel, uint32_t frame_format, picture_t *picture, - int code) -{ - - if ( !picture->current_frame ) return; - - if (frame_format == XINE_IMGFMT_XXMC) { - xine_xxmc_t *xxmc = (xine_xxmc_t *) - picture->current_frame->accel_data; - if (!xxmc->decoded) { - switch(picture->current_frame->format) { - case XINE_IMGFMT_XXMC: - switch(xxmc->acceleration) { - case XINE_XVMC_ACCEL_VLD: - mpeg2_xxmc_vld_frame_complete(accel, picture, code); - break; - case XINE_XVMC_ACCEL_IDCT: - case XINE_XVMC_ACCEL_MOCOMP: - xxmc->decoded = !picture->current_frame->bad_frame; - xxmc->proc_xxmc_flush( picture->current_frame ); - break; - default: - break; - } - default: - break; - } - } - } -} - - -int -libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, char * buffer, - uint32_t chunk_size, uint8_t *chunk_buffer) -{ - /* - * Don't reference frames of other formats. They are invalid. This may happen if the - * xxmc plugin suddenly falls back to software decoding. - */ - - if (( picture->current_frame->picture_coding_type == XINE_PICT_P_TYPE ) || - ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE )) { - if (! picture->forward_reference_frame) return 1; - if (picture->forward_reference_frame->format != picture->current_frame->format) { - picture->v_offset = 0; - return 1; - } - } - - if ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE ) { - if (! picture->backward_reference_frame) return 1; - if (picture->backward_reference_frame->format != picture->current_frame->format) { - picture->v_offset = 0; - return 1; - } - } - - switch( picture->current_frame->format ) { - - case XINE_IMGFMT_XXMC: - { - xine_xxmc_t *xxmc = (xine_xxmc_t *) - picture->current_frame->accel_data; - - if ( xxmc->proc_xxmc_lock_valid( picture->current_frame, - picture->forward_reference_frame, - picture->backward_reference_frame, - picture->current_frame->picture_coding_type)) { - picture->v_offset = 0; - return 1; - } - - switch(picture->current_frame->format) { - case XINE_IMGFMT_XXMC: - switch(xxmc->acceleration) { - case XINE_XVMC_ACCEL_VLD: - mpeg2_xxmc_slice(accel, picture, code, buffer, chunk_size, chunk_buffer); - break; - case XINE_XVMC_ACCEL_IDCT: - case XINE_XVMC_ACCEL_MOCOMP: - mpeg2_xvmc_slice (accel, picture, code, buffer); - break; - default: - mpeg2_slice (picture, code, buffer); - break; - } - break; - default: - mpeg2_slice (picture, code, buffer); - break; - } - xxmc->proc_xxmc_unlock(picture->current_frame->driver); - break; - } - - case XINE_IMGFMT_XVMC: - mpeg2_xvmc_slice (accel, picture, code, buffer); - break; - - default: - mpeg2_slice (picture, code, buffer); - break; - } - return 0; -} diff --git a/src/libmpeg2/libmpeg2_accel.h b/src/libmpeg2/libmpeg2_accel.h deleted file mode 100644 index 5d0b37a78..000000000 --- a/src/libmpeg2/libmpeg2_accel.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * libmpeg2_accel.h - * Copyright (C) 2004 The Unichrome Project. - * Copyright (C) 2005 Thomas Hellstrom. - * - * 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 - */ - -#ifndef LIBMPEG2_ACCEL_H -#define LIBMPEG2_ACCEL_H - -#include "mpeg2_internal.h" - -/* - * Internal context data type. - */ - -typedef struct { - int xvmc_last_slice_code; - int slices_per_row; - int row_slice_count; - unsigned xxmc_mb_pic_height; -} mpeg2dec_accel_t; - -extern int libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture); -extern int libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture); -extern int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, double ratio, uint32_t flags); -extern void libmpeg2_accel_frame_completion(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, int code); - -extern int libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, - char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer); -extern void libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt); - -#endif diff --git a/src/libmpeg2/motion_comp.c b/src/libmpeg2/motion_comp.c deleted file mode 100644 index 9328dfb9f..000000000 --- a/src/libmpeg2/motion_comp.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * motion_comp.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#include -#include - -#include "mpeg2_internal.h" -#include - -mpeg2_mc_t mpeg2_mc; - -void mpeg2_mc_init (uint32_t mm_accel) -{ -#ifdef LIBMPEG2_MLIB - if (mm_accel & MM_ACCEL_MLIB) { -#ifdef LOG - fprintf (stderr, "Using mediaLib for motion compensation\n"); -#endif - mpeg2_mc = mpeg2_mc_mlib; - } -#endif - -#if defined(ARCH_X86) || defined(ARCH_X86_64) - if (mm_accel & MM_ACCEL_X86_MMXEXT) { -#ifdef LOG - fprintf (stderr, "Using MMXEXT for motion compensation\n"); -#endif - mpeg2_mc = mpeg2_mc_mmxext; - } else if (mm_accel & MM_ACCEL_X86_3DNOW) { -#ifdef LOG - fprintf (stderr, "Using 3DNOW for motion compensation\n"); -#endif - mpeg2_mc = mpeg2_mc_3dnow; - } else if (mm_accel & MM_ACCEL_X86_MMX) { -#ifdef LOG - fprintf (stderr, "Using MMX for motion compensation\n"); -#endif - mpeg2_mc = mpeg2_mc_mmx; - } else -#endif -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) - if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { -#ifdef LOG - fprintf (stderr, "Using altivec for motion compensation\n"); -#endif - mpeg2_mc = mpeg2_mc_altivec; - } else -#endif -#ifdef ARCH_SPARC - if (mm_accel & MM_ACCEL_SPARC_VIS) { -#ifdef LOG - fprintf (stderr, "Using VIS for motion compensation\n"); -#endif - mpeg2_mc = mpeg2_mc_vis; - } else -#endif - { -#ifdef LOG - fprintf (stderr, "No accelerated motion compensation found\n"); -#endif - mpeg2_mc = mpeg2_mc_c; - } -} - -#define avg2(a,b) ((a+b+1)>>1) -#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) - -#define predict_o(i) (ref[i]) -#define predict_x(i) (avg2 (ref[i], ref[i+1])) -#define predict_y(i) (avg2 (ref[i], (ref+stride)[i])) -#define predict_xy(i) (avg4 (ref[i], ref[i+1], \ - (ref+stride)[i], (ref+stride)[i+1])) - -#define put(predictor,i) dest[i] = predictor (i) -#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i]) - -/* mc function template */ - -#define MC_FUNC(op,xy) \ -static void MC_##op##_##xy##_16_c (uint8_t * dest, uint8_t * ref, \ - int stride, int height) \ -{ \ - do { \ - op (predict_##xy, 0); \ - op (predict_##xy, 1); \ - op (predict_##xy, 2); \ - op (predict_##xy, 3); \ - op (predict_##xy, 4); \ - op (predict_##xy, 5); \ - op (predict_##xy, 6); \ - op (predict_##xy, 7); \ - op (predict_##xy, 8); \ - op (predict_##xy, 9); \ - op (predict_##xy, 10); \ - op (predict_##xy, 11); \ - op (predict_##xy, 12); \ - op (predict_##xy, 13); \ - op (predict_##xy, 14); \ - op (predict_##xy, 15); \ - ref += stride; \ - dest += stride; \ - } while (--height); \ -} \ -static void MC_##op##_##xy##_8_c (uint8_t * dest, uint8_t * ref, \ - int stride, int height) \ -{ \ - do { \ - op (predict_##xy, 0); \ - op (predict_##xy, 1); \ - op (predict_##xy, 2); \ - op (predict_##xy, 3); \ - op (predict_##xy, 4); \ - op (predict_##xy, 5); \ - op (predict_##xy, 6); \ - op (predict_##xy, 7); \ - ref += stride; \ - dest += stride; \ - } while (--height); \ -} - -/* definitions of the actual mc functions */ - -MC_FUNC (put,o) -MC_FUNC (avg,o) -MC_FUNC (put,x) -MC_FUNC (avg,x) -MC_FUNC (put,y) -MC_FUNC (avg,y) -MC_FUNC (put,xy) -MC_FUNC (avg,xy) - -MPEG2_MC_EXTERN (c) diff --git a/src/libmpeg2/motion_comp_altivec.c b/src/libmpeg2/motion_comp_altivec.c deleted file mode 100644 index 99719b7fb..000000000 --- a/src/libmpeg2/motion_comp_altivec.c +++ /dev/null @@ -1,2031 +0,0 @@ -/* - * motion_comp_altivec.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#ifndef HOST_OS_DARWIN - -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) - -#include "mpeg2_internal.h" - -#include - -/* - * The asm code is generated with: - * - * gcc-2.95 -fvec -DHOST_OS_DARWIN -O9 -fomit-frame-pointer -mregnames -S - * motion_comp_altivec.c - * - * sed 's/.L/._L/g' motion_comp_altivec.s | - * awk '{args=""; len=split ($2, arg, ","); - * for (i=1; i<=len; i++) { a=arg[i]; if (i> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - tmp = vec_perm (ref0, ref1, perm); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - vec_st (tmp, 0, dest); - tmp = vec_perm (ref0, ref1, perm); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - vec_st (tmp, stride, dest); - dest += 2*stride; - tmp = vec_perm (ref0, ref1, perm); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - vec_st (tmp, 0, dest); - tmp = vec_perm (ref0, ref1, perm); - vec_st (tmp, stride, dest); -} - -void MC_put_o_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1; - - tmp0 = vec_lvsl (0, ref); - tmp0 = vec_mergeh (tmp0, tmp0); - perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); - tmp1 = vec_lvsl (stride, ref); - tmp1 = vec_mergeh (tmp1, tmp1); - perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_perm (ref0, ref1, perm1); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_perm (ref0, ref1, perm1); - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); -} - -void MC_put_x_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t permA, permB, ref0, ref1, tmp; - - permA = vec_lvsl (0, ref); - permB = vec_add (permA, vec_splat_u8 (1)); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - tmp = vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB)); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - vec_st (tmp, 0, dest); - tmp = vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB)); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - vec_st (tmp, stride, dest); - dest += 2*stride; - tmp = vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB)); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - vec_st (tmp, 0, dest); - tmp = vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB)); - vec_st (tmp, stride, dest); -} - -void MC_put_x_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; - - ones = vec_splat_u8 (1); - tmp0 = vec_lvsl (0, ref); - tmp0 = vec_mergeh (tmp0, tmp0); - perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); - perm0B = vec_add (perm0A, ones); - tmp1 = vec_lvsl (stride, ref); - tmp1 = vec_mergeh (tmp1, tmp1); - perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); - perm1B = vec_add (perm1A, ones); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - ref += stride; - tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), - vec_perm (ref0, ref1, perm0B)); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), - vec_perm (ref0, ref1, perm1B)); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), - vec_perm (ref0, ref1, perm0B)); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), - vec_perm (ref0, ref1, perm1B)); - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); -} - -void MC_put_y_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp; - - perm = vec_lvsl (0, ref); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - tmp0 = vec_perm (ref0, ref1, perm); - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - tmp1 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (tmp0, tmp1); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - vec_st (tmp, 0, dest); - tmp0 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (tmp0, tmp1); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - vec_st (tmp, stride, dest); - dest += 2*stride; - tmp1 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (tmp0, tmp1); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - vec_st (tmp, 0, dest); - tmp0 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (tmp0, tmp1); - vec_st (tmp, stride, dest); -} - -void MC_put_y_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1; - - tmp0 = vec_lvsl (0, ref); - tmp0 = vec_mergeh (tmp0, tmp0); - perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); - tmp1 = vec_lvsl (stride, ref); - tmp1 = vec_mergeh (tmp1, tmp1); - perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - tmp1 = vec_perm (ref0, ref1, perm1); - tmp = vec_avg (tmp0, tmp1); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - tmp = vec_avg (tmp0, tmp1); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_perm (ref0, ref1, perm1); - tmp = vec_avg (tmp0, tmp1); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - tmp = vec_avg (tmp0, tmp1); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); -} - -void MC_put_xy_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; - vector_u8_t ones; - - ones = vec_splat_u8 (1); - permA = vec_lvsl (0, ref); - permB = vec_add (permA, ones); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - vec_st (tmp, 0, dest); - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - vec_st (tmp, stride, dest); - dest += 2*stride; - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - vec_st (tmp, 0, dest); - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - vec_st (tmp, stride, dest); -} - -void MC_put_xy_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; - vector_u8_t avg0, avg1, xor0, xor1, tmp, ones; - - ones = vec_splat_u8 (1); - perm0A = vec_lvsl (0, ref); - perm0A = vec_mergeh (perm0A, perm0A); - perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); - perm0B = vec_add (perm0A, ones); - perm1A = vec_lvsl (stride, ref); - perm1A = vec_mergeh (perm1A, perm1A); - perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); - perm1B = vec_add (perm1A, ones); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, perm0A); - B = vec_perm (ref0, ref1, perm0B); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, perm1A); - B = vec_perm (ref0, ref1, perm1B); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - A = vec_perm (ref0, ref1, perm0A); - B = vec_perm (ref0, ref1, perm0B); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - A = vec_perm (ref0, ref1, perm1A); - B = vec_perm (ref0, ref1, perm1B); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - A = vec_perm (ref0, ref1, perm0A); - B = vec_perm (ref0, ref1, perm0B); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1))); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); -} - -#if 0 -void MC_put_xy_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t permA, permB, ref0, ref1, A, B, C, D, tmp, zero, ones; - vector_u16_t splat2, temp; - - ones = vec_splat_u8 (1); - permA = vec_lvsl (0, ref); - permB = vec_add (permA, ones); - - zero = vec_splat_u8 (0); - splat2 = vec_splat_u16 (2); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - C = vec_perm (ref0, ref1, permA); - D = vec_perm (ref0, ref1, permB); - - temp = vec_add (vec_add ((vector_u16_t)vec_mergeh (zero, A), - (vector_u16_t)vec_mergeh (zero, B)), - vec_add ((vector_u16_t)vec_mergeh (zero, C), - (vector_u16_t)vec_mergeh (zero, D))); - temp = vec_sr (vec_add (temp, splat2), splat2); - tmp = vec_pack (temp, temp); - - vec_st (tmp, 0, dest); - dest += stride; - tmp = vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB)); - } while (--height); -} -#endif - -void MC_avg_o_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm, ref0, ref1, tmp, prev; - - perm = vec_lvsl (0, ref); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - prev = vec_ld (0, dest); - tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - prev = vec_ld (2*stride, dest); - vec_st (tmp, stride, dest); - dest += 2*stride; - tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); - vec_st (tmp, stride, dest); -} - -void MC_avg_o_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1, prev; - - tmp0 = vec_lvsl (0, ref); - tmp0 = vec_mergeh (tmp0, tmp0); - perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); - tmp1 = vec_lvsl (stride, ref); - tmp1 = vec_mergeh (tmp1, tmp1); - perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - prev = vec_ld (0, dest); - tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); -} - -void MC_avg_x_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t permA, permB, ref0, ref1, tmp, prev; - - permA = vec_lvsl (0, ref); - permB = vec_add (permA, vec_splat_u8 (1)); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - prev = vec_ld (0, dest); - ref += stride; - tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB))); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB))); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (2*stride, dest); - vec_st (tmp, stride, dest); - dest += 2*stride; - tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB))); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), - vec_perm (ref0, ref1, permB))); - vec_st (tmp, stride, dest); -} - -void MC_avg_x_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; - vector_u8_t prev; - - ones = vec_splat_u8 (1); - tmp0 = vec_lvsl (0, ref); - tmp0 = vec_mergeh (tmp0, tmp0); - perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); - perm0B = vec_add (perm0A, ones); - tmp1 = vec_lvsl (stride, ref); - tmp1 = vec_mergeh (tmp1, tmp1); - perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); - perm1B = vec_add (perm1A, ones); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - prev = vec_ld (0, dest); - ref += stride; - tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), - vec_perm (ref0, ref1, perm0B))); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), - vec_perm (ref0, ref1, perm1B))); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), - vec_perm (ref0, ref1, perm0B))); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (8, ref); - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), - vec_perm (ref0, ref1, perm1B))); - vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); -} - -void MC_avg_y_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp, prev; - - perm = vec_lvsl (0, ref); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - tmp0 = vec_perm (ref0, ref1, perm); - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - prev = vec_ld (0, dest); - tmp1 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - tmp0 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - ref += stride; - prev = vec_ld (2*stride, dest); - vec_st (tmp, stride, dest); - dest += 2*stride; - tmp1 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (15, ref); - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - tmp0 = vec_perm (ref0, ref1, perm); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - vec_st (tmp, stride, dest); -} - -void MC_avg_y_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1, prev; - - tmp0 = vec_lvsl (0, ref); - tmp0 = vec_mergeh (tmp0, tmp0); - perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); - tmp1 = vec_lvsl (stride, ref); - tmp1 = vec_mergeh (tmp1, tmp1); - perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - prev = vec_ld (0, dest); - tmp1 = vec_perm (ref0, ref1, perm1); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - tmp1 = vec_perm (ref0, ref1, perm1); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (7, ref); - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - tmp0 = vec_perm (ref0, ref1, perm0); - tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); -} - -void MC_avg_xy_16_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; - vector_u8_t ones, prev; - - ones = vec_splat_u8 (1); - permA = vec_lvsl (0, ref); - permB = vec_add (permA, ones); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (0, dest); - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_avg (prev, - vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (2*stride, dest); - vec_st (tmp, stride, dest); - dest += 2*stride; - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_avg (prev, - vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - prev = vec_ld (stride, dest); - vec_st (tmp, 0, dest); - A = vec_perm (ref0, ref1, permA); - B = vec_perm (ref0, ref1, permB); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - vec_st (tmp, stride, dest); -} - -void MC_avg_xy_8_altivec (unsigned char * dest, unsigned char * ref, - int stride, int height) -{ - vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; - vector_u8_t avg0, avg1, xor0, xor1, tmp, ones, prev; - - ones = vec_splat_u8 (1); - perm0A = vec_lvsl (0, ref); - perm0A = vec_mergeh (perm0A, perm0A); - perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); - perm0B = vec_add (perm0A, ones); - perm1A = vec_lvsl (stride, ref); - perm1A = vec_mergeh (perm1A, perm1A); - perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); - perm1B = vec_add (perm1A, ones); - - height = (height >> 1) - 1; - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - A = vec_perm (ref0, ref1, perm0A); - B = vec_perm (ref0, ref1, perm0B); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (0, dest); - A = vec_perm (ref0, ref1, perm1A); - B = vec_perm (ref0, ref1, perm1B); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - - - do { - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - A = vec_perm (ref0, ref1, perm0A); - B = vec_perm (ref0, ref1, perm0B); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_avg (prev, - vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - ref += stride; - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - A = vec_perm (ref0, ref1, perm1A); - B = vec_perm (ref0, ref1, perm1B); - avg1 = vec_avg (A, B); - xor1 = vec_xor (A, B); - tmp = vec_avg (prev, - vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - } while (--height); - - ref0 = vec_ld (0, ref); - ref1 = vec_ld (16, ref); - prev = vec_ld (stride, dest); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); - dest += stride; - A = vec_perm (ref0, ref1, perm0A); - B = vec_perm (ref0, ref1, perm0B); - avg0 = vec_avg (A, B); - xor0 = vec_xor (A, B); - tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), - vec_and (vec_and (ones, vec_or (xor0, xor1)), - vec_xor (avg0, avg1)))); - vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); - vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); -} - -MPEG2_MC_EXTERN (altivec) - -#endif /* ENABLE_ALTIVEC */ - -#endif /* HOST_OS_DARWIN */ - diff --git a/src/libmpeg2/motion_comp_mlib.c b/src/libmpeg2/motion_comp_mlib.c deleted file mode 100644 index 1a37070ae..000000000 --- a/src/libmpeg2/motion_comp_mlib.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * motion_comp_mlib.c - * Copyright (C) 2000-2002 Håkan Hjort - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#ifdef LIBMPEG2_MLIB - -#include -#include -#include -#include -#include - -#include "mpeg2_internal.h" - -static void MC_put_o_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoCopyRef_U8_U8_16x16 (dest, ref, stride); - else - mlib_VideoCopyRef_U8_U8_16x8 (dest, ref, stride); -} - -static void MC_put_x_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoInterpX_U8_U8_16x16 (dest, ref, stride, stride); - else - mlib_VideoInterpX_U8_U8_16x8 (dest, ref, stride, stride); -} - -static void MC_put_y_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoInterpY_U8_U8_16x16 (dest, ref, stride, stride); - else - mlib_VideoInterpY_U8_U8_16x8 (dest, ref, stride, stride); -} - -static void MC_put_xy_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoInterpXY_U8_U8_16x16 (dest, ref, stride, stride); - else - mlib_VideoInterpXY_U8_U8_16x8 (dest, ref, stride, stride); -} - -static void MC_put_o_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoCopyRef_U8_U8_8x8 (dest, ref, stride); - else - mlib_VideoCopyRef_U8_U8_8x4 (dest, ref, stride); -} - -static void MC_put_x_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoInterpX_U8_U8_8x8 (dest, ref, stride, stride); - else - mlib_VideoInterpX_U8_U8_8x4 (dest, ref, stride, stride); -} - -static void MC_put_y_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoInterpY_U8_U8_8x8 (dest, ref, stride, stride); - else - mlib_VideoInterpY_U8_U8_8x4 (dest, ref, stride, stride); -} - -static void MC_put_xy_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoInterpXY_U8_U8_8x8 (dest, ref, stride, stride); - else - mlib_VideoInterpXY_U8_U8_8x4 (dest, ref, stride, stride); -} - -static void MC_avg_o_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoCopyRefAve_U8_U8_16x16 (dest, ref, stride); - else - mlib_VideoCopyRefAve_U8_U8_16x8 (dest, ref, stride); -} - -static void MC_avg_x_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoInterpAveX_U8_U8_16x16 (dest, ref, stride, stride); - else - mlib_VideoInterpAveX_U8_U8_16x8 (dest, ref, stride, stride); -} - -static void MC_avg_y_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoInterpAveY_U8_U8_16x16 (dest, ref, stride, stride); - else - mlib_VideoInterpAveY_U8_U8_16x8 (dest, ref, stride, stride); -} - -static void MC_avg_xy_16_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 16) - mlib_VideoInterpAveXY_U8_U8_16x16 (dest, ref, stride, stride); - else - mlib_VideoInterpAveXY_U8_U8_16x8 (dest, ref, stride, stride); -} - -static void MC_avg_o_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoCopyRefAve_U8_U8_8x8 (dest, ref, stride); - else - mlib_VideoCopyRefAve_U8_U8_8x4 (dest, ref, stride); -} - -static void MC_avg_x_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoInterpAveX_U8_U8_8x8 (dest, ref, stride, stride); - else - mlib_VideoInterpAveX_U8_U8_8x4 (dest, ref, stride, stride); -} - -static void MC_avg_y_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoInterpAveY_U8_U8_8x8 (dest, ref, stride, stride); - else - mlib_VideoInterpAveY_U8_U8_8x4 (dest, ref, stride, stride); -} - -static void MC_avg_xy_8_mlib (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - if (height == 8) - mlib_VideoInterpAveXY_U8_U8_8x8 (dest, ref, stride, stride); - else - mlib_VideoInterpAveXY_U8_U8_8x4 (dest, ref, stride, stride); -} - -MPEG2_MC_EXTERN (mlib) - -#endif diff --git a/src/libmpeg2/motion_comp_mmx.c b/src/libmpeg2/motion_comp_mmx.c deleted file mode 100644 index f9b1f085d..000000000 --- a/src/libmpeg2/motion_comp_mmx.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * motion_comp_mmx.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#if defined(ARCH_X86) || defined(ARCH_X86_64) - -#include - -#include "mpeg2_internal.h" -#include - -#define CPU_MMXEXT 0 -#define CPU_3DNOW 1 - - -/* MMX code - needs a rewrite */ - -/* some rounding constants */ -static mmx_t round1 = {0x0001000100010001LL}; -static mmx_t round4 = {0x0002000200020002LL}; - -/* - * This code should probably be compiled with loop unrolling - * (ie, -funroll-loops in gcc)becuase some of the loops - * use a small static number of iterations. This was written - * with the assumption the compiler knows best about when - * unrolling will help - */ - -static inline void mmx_zero_reg () -{ - /* load 0 into mm0 */ - pxor_r2r (mm0, mm0); -} - -static inline void mmx_average_2_U8 (uint8_t * dest, - uint8_t * src1, uint8_t * src2) -{ - /* *dest = (*src1 + *src2 + 1)/ 2; */ - - movq_m2r (*src1, mm1); // load 8 src1 bytes - movq_r2r (mm1, mm2); // copy 8 src1 bytes - - movq_m2r (*src2, mm3); // load 8 src2 bytes - movq_r2r (mm3, mm4); // copy 8 src2 bytes - - punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes - punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes - - punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes - punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes - - paddw_r2r (mm3, mm1); // add lows to mm1 - paddw_m2r (round1, mm1); - psraw_i2r (1, mm1); // /2 - - paddw_r2r (mm4, mm2); // add highs to mm2 - paddw_m2r (round1, mm2); - psraw_i2r (1, mm2); // /2 - - packuswb_r2r (mm2, mm1); // pack (w/ saturation) - movq_r2m (mm1, *dest); // store result in dest -} - -static inline void mmx_interp_average_2_U8 (uint8_t * dest, - uint8_t * src1, uint8_t * src2) -{ - /* *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; */ - - movq_m2r (*dest, mm1); // load 8 dest bytes - movq_r2r (mm1, mm2); // copy 8 dest bytes - - movq_m2r (*src1, mm3); // load 8 src1 bytes - movq_r2r (mm3, mm4); // copy 8 src1 bytes - - movq_m2r (*src2, mm5); // load 8 src2 bytes - movq_r2r (mm5, mm6); // copy 8 src2 bytes - - punpcklbw_r2r (mm0, mm1); // unpack low dest bytes - punpckhbw_r2r (mm0, mm2); // unpack high dest bytes - - punpcklbw_r2r (mm0, mm3); // unpack low src1 bytes - punpckhbw_r2r (mm0, mm4); // unpack high src1 bytes - - punpcklbw_r2r (mm0, mm5); // unpack low src2 bytes - punpckhbw_r2r (mm0, mm6); // unpack high src2 bytes - - paddw_r2r (mm5, mm3); // add lows - paddw_m2r (round1, mm3); - psraw_i2r (1, mm3); // /2 - - paddw_r2r (mm6, mm4); // add highs - paddw_m2r (round1, mm4); - psraw_i2r (1, mm4); // /2 - - paddw_r2r (mm3, mm1); // add lows - paddw_m2r (round1, mm1); - psraw_i2r (1, mm1); // /2 - - paddw_r2r (mm4, mm2); // add highs - paddw_m2r (round1, mm2); - psraw_i2r (1, mm2); // /2 - - packuswb_r2r (mm2, mm1); // pack (w/ saturation) - movq_r2m (mm1, *dest); // store result in dest -} - -static inline void mmx_average_4_U8 (uint8_t * dest, - uint8_t * src1, uint8_t * src2, - uint8_t * src3, uint8_t * src4) -{ - /* *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; */ - - movq_m2r (*src1, mm1); // load 8 src1 bytes - movq_r2r (mm1, mm2); // copy 8 src1 bytes - - punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes - punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes - - movq_m2r (*src2, mm3); // load 8 src2 bytes - movq_r2r (mm3, mm4); // copy 8 src2 bytes - - punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes - punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes - - paddw_r2r (mm3, mm1); // add lows - paddw_r2r (mm4, mm2); // add highs - - /* now have partials in mm1 and mm2 */ - - movq_m2r (*src3, mm3); // load 8 src3 bytes - movq_r2r (mm3, mm4); // copy 8 src3 bytes - - punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes - punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes - - paddw_r2r (mm3, mm1); // add lows - paddw_r2r (mm4, mm2); // add highs - - movq_m2r (*src4, mm5); // load 8 src4 bytes - movq_r2r (mm5, mm6); // copy 8 src4 bytes - - punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes - punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes - - paddw_r2r (mm5, mm1); // add lows - paddw_r2r (mm6, mm2); // add highs - - /* now have subtotal in mm1 and mm2 */ - - paddw_m2r (round4, mm1); - psraw_i2r (2, mm1); // /4 - paddw_m2r (round4, mm2); - psraw_i2r (2, mm2); // /4 - - packuswb_r2r (mm2, mm1); // pack (w/ saturation) - movq_r2m (mm1, *dest); // store result in dest -} - -static inline void mmx_interp_average_4_U8 (uint8_t * dest, - uint8_t * src1, uint8_t * src2, - uint8_t * src3, uint8_t * src4) -{ - /* *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; */ - - movq_m2r (*src1, mm1); // load 8 src1 bytes - movq_r2r (mm1, mm2); // copy 8 src1 bytes - - punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes - punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes - - movq_m2r (*src2, mm3); // load 8 src2 bytes - movq_r2r (mm3, mm4); // copy 8 src2 bytes - - punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes - punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes - - paddw_r2r (mm3, mm1); // add lows - paddw_r2r (mm4, mm2); // add highs - - /* now have partials in mm1 and mm2 */ - - movq_m2r (*src3, mm3); // load 8 src3 bytes - movq_r2r (mm3, mm4); // copy 8 src3 bytes - - punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes - punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes - - paddw_r2r (mm3, mm1); // add lows - paddw_r2r (mm4, mm2); // add highs - - movq_m2r (*src4, mm5); // load 8 src4 bytes - movq_r2r (mm5, mm6); // copy 8 src4 bytes - - punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes - punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes - - paddw_r2r (mm5, mm1); // add lows - paddw_r2r (mm6, mm2); // add highs - - paddw_m2r (round4, mm1); - psraw_i2r (2, mm1); // /4 - paddw_m2r (round4, mm2); - psraw_i2r (2, mm2); // /4 - - /* now have subtotal/4 in mm1 and mm2 */ - - movq_m2r (*dest, mm3); // load 8 dest bytes - movq_r2r (mm3, mm4); // copy 8 dest bytes - - punpcklbw_r2r (mm0, mm3); // unpack low dest bytes - punpckhbw_r2r (mm0, mm4); // unpack high dest bytes - - paddw_r2r (mm3, mm1); // add lows - paddw_r2r (mm4, mm2); // add highs - - paddw_m2r (round1, mm1); - psraw_i2r (1, mm1); // /2 - paddw_m2r (round1, mm2); - psraw_i2r (1, mm2); // /2 - - /* now have end value in mm1 and mm2 */ - - packuswb_r2r (mm2, mm1); // pack (w/ saturation) - movq_r2m (mm1,*dest); // store result in dest -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_avg_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - mmx_zero_reg (); - - do { - mmx_average_2_U8 (dest, dest, ref); - - if (width == 16) - mmx_average_2_U8 (dest+8, dest+8, ref+8); - - dest += stride; - ref += stride; - } while (--height); -} - -static void MC_avg_o_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_mmx (16, height, dest, ref, stride); -} - -static void MC_avg_o_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_put_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - mmx_zero_reg (); - - do { - movq_m2r (* ref, mm1); // load 8 ref bytes - movq_r2m (mm1,* dest); // store 8 bytes at curr - - if (width == 16) - { - movq_m2r (* (ref+8), mm1); // load 8 ref bytes - movq_r2m (mm1,* (dest+8)); // store 8 bytes at curr - } - - dest += stride; - ref += stride; - } while (--height); -} - -static void MC_put_o_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_mmx (16, height, dest, ref, stride); -} - -static void MC_put_o_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -/* Half pixel interpolation in the x direction */ -static inline void MC_avg_x_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - mmx_zero_reg (); - - do { - mmx_interp_average_2_U8 (dest, ref, ref+1); - - if (width == 16) - mmx_interp_average_2_U8 (dest+8, ref+8, ref+9); - - dest += stride; - ref += stride; - } while (--height); -} - -static void MC_avg_x_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_x_mmx (16, height, dest, ref, stride); -} - -static void MC_avg_x_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_x_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_put_x_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - mmx_zero_reg (); - - do { - mmx_average_2_U8 (dest, ref, ref+1); - - if (width == 16) - mmx_average_2_U8 (dest+8, ref+8, ref+9); - - dest += stride; - ref += stride; - } while (--height); -} - -static void MC_put_x_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_x_mmx (16, height, dest, ref, stride); -} - -static void MC_put_x_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_x_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_avg_xy_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - uint8_t * ref_next = ref+stride; - - mmx_zero_reg (); - - do { - mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); - - if (width == 16) - mmx_interp_average_4_U8 (dest+8, ref+8, ref+9, - ref_next+8, ref_next+9); - - dest += stride; - ref += stride; - ref_next += stride; - } while (--height); -} - -static void MC_avg_xy_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_xy_mmx (16, height, dest, ref, stride); -} - -static void MC_avg_xy_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_xy_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_put_xy_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - uint8_t * ref_next = ref+stride; - - mmx_zero_reg (); - - do { - mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); - - if (width == 16) - mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); - - dest += stride; - ref += stride; - ref_next += stride; - } while (--height); -} - -static void MC_put_xy_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_xy_mmx (16, height, dest, ref, stride); -} - -static void MC_put_xy_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_xy_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_avg_y_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - uint8_t * ref_next = ref+stride; - - mmx_zero_reg (); - - do { - mmx_interp_average_2_U8 (dest, ref, ref_next); - - if (width == 16) - mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8); - - dest += stride; - ref += stride; - ref_next += stride; - } while (--height); -} - -static void MC_avg_y_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_y_mmx (16, height, dest, ref, stride); -} - -static void MC_avg_y_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg_y_mmx (8, height, dest, ref, stride); -} - -/*-----------------------------------------------------------------------*/ - -static inline void MC_put_y_mmx (int width, int height, - uint8_t * dest, uint8_t * ref, int stride) -{ - uint8_t * ref_next = ref+stride; - - mmx_zero_reg (); - - do { - mmx_average_2_U8 (dest, ref, ref_next); - - if (width == 16) - mmx_average_2_U8 (dest+8, ref+8, ref_next+8); - - dest += stride; - ref += stride; - ref_next += stride; - } while (--height); -} - -static void MC_put_y_16_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_y_mmx (16, height, dest, ref, stride); -} - -static void MC_put_y_8_mmx (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put_y_mmx (8, height, dest, ref, stride); -} - - -MPEG2_MC_EXTERN (mmx) - - - - - - - -/* CPU_MMXEXT/CPU_3DNOW adaptation layer */ - -#define pavg_r2r(src,dest) \ -do { \ - if (cpu == CPU_MMXEXT) \ - pavgb_r2r (src, dest); \ - else \ - pavgusb_r2r (src, dest); \ -} while (0) - -#define pavg_m2r(src,dest) \ -do { \ - if (cpu == CPU_MMXEXT) \ - pavgb_m2r (src, dest); \ - else \ - pavgusb_m2r (src, dest); \ -} while (0) - - -/* CPU_MMXEXT code */ - - -static inline void MC_put1_8 (int height, uint8_t * dest, uint8_t * ref, - int stride) -{ - do { - movq_m2r (*ref, mm0); - movq_r2m (mm0, *dest); - ref += stride; - dest += stride; - } while (--height); -} - -static inline void MC_put1_16 (int height, uint8_t * dest, uint8_t * ref, - int stride) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+8), mm1); - ref += stride; - movq_r2m (mm0, *dest); - movq_r2m (mm1, *(dest+8)); - dest += stride; - } while (--height); -} - -static inline void MC_avg1_8 (int height, uint8_t * dest, uint8_t * ref, - int stride, int cpu) -{ - do { - movq_m2r (*ref, mm0); - pavg_m2r (*dest, mm0); - ref += stride; - movq_r2m (mm0, *dest); - dest += stride; - } while (--height); -} - -static inline void MC_avg1_16 (int height, uint8_t * dest, uint8_t * ref, - int stride, int cpu) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+8), mm1); - pavg_m2r (*dest, mm0); - pavg_m2r (*(dest+8), mm1); - movq_r2m (mm0, *dest); - ref += stride; - movq_r2m (mm1, *(dest+8)); - dest += stride; - } while (--height); -} - -static inline void MC_put2_8 (int height, uint8_t * dest, uint8_t * ref, - int stride, int offset, int cpu) -{ - do { - movq_m2r (*ref, mm0); - pavg_m2r (*(ref+offset), mm0); - ref += stride; - movq_r2m (mm0, *dest); - dest += stride; - } while (--height); -} - -static inline void MC_put2_16 (int height, uint8_t * dest, uint8_t * ref, - int stride, int offset, int cpu) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+8), mm1); - pavg_m2r (*(ref+offset), mm0); - pavg_m2r (*(ref+offset+8), mm1); - movq_r2m (mm0, *dest); - ref += stride; - movq_r2m (mm1, *(dest+8)); - dest += stride; - } while (--height); -} - -static inline void MC_avg2_8 (int height, uint8_t * dest, uint8_t * ref, - int stride, int offset, int cpu) -{ - do { - movq_m2r (*ref, mm0); - pavg_m2r (*(ref+offset), mm0); - pavg_m2r (*dest, mm0); - ref += stride; - movq_r2m (mm0, *dest); - dest += stride; - } while (--height); -} - -static inline void MC_avg2_16 (int height, uint8_t * dest, uint8_t * ref, - int stride, int offset, int cpu) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+8), mm1); - pavg_m2r (*(ref+offset), mm0); - pavg_m2r (*(ref+offset+8), mm1); - pavg_m2r (*dest, mm0); - pavg_m2r (*(dest+8), mm1); - ref += stride; - movq_r2m (mm0, *dest); - movq_r2m (mm1, *(dest+8)); - dest += stride; - } while (--height); -} - -static mmx_t mask_one = {0x0101010101010101LL}; - -static inline void MC_put4_8 (int height, uint8_t * dest, uint8_t * ref, - int stride, int cpu) -{ - movq_m2r (*ref, mm0); - movq_m2r (*(ref+1), mm1); - movq_r2r (mm0, mm7); - pxor_r2r (mm1, mm7); - pavg_r2r (mm1, mm0); - ref += stride; - - do { - movq_m2r (*ref, mm2); - movq_r2r (mm0, mm5); - - movq_m2r (*(ref+1), mm3); - movq_r2r (mm2, mm6); - - pxor_r2r (mm3, mm6); - pavg_r2r (mm3, mm2); - - por_r2r (mm6, mm7); - pxor_r2r (mm2, mm5); - - pand_r2r (mm5, mm7); - pavg_r2r (mm2, mm0); - - pand_m2r (mask_one, mm7); - - psubusb_r2r (mm7, mm0); - - ref += stride; - movq_r2m (mm0, *dest); - dest += stride; - - movq_r2r (mm6, mm7); // unroll ! - movq_r2r (mm2, mm0); // unroll ! - } while (--height); -} - -static inline void MC_put4_16 (int height, uint8_t * dest, uint8_t * ref, - int stride, int cpu) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+stride+1), mm1); - movq_r2r (mm0, mm7); - movq_m2r (*(ref+1), mm2); - pxor_r2r (mm1, mm7); - movq_m2r (*(ref+stride), mm3); - movq_r2r (mm2, mm6); - pxor_r2r (mm3, mm6); - pavg_r2r (mm1, mm0); - pavg_r2r (mm3, mm2); - por_r2r (mm6, mm7); - movq_r2r (mm0, mm6); - pxor_r2r (mm2, mm6); - pand_r2r (mm6, mm7); - pand_m2r (mask_one, mm7); - pavg_r2r (mm2, mm0); - psubusb_r2r (mm7, mm0); - movq_r2m (mm0, *dest); - - movq_m2r (*(ref+8), mm0); - movq_m2r (*(ref+stride+9), mm1); - movq_r2r (mm0, mm7); - movq_m2r (*(ref+9), mm2); - pxor_r2r (mm1, mm7); - movq_m2r (*(ref+stride+8), mm3); - movq_r2r (mm2, mm6); - pxor_r2r (mm3, mm6); - pavg_r2r (mm1, mm0); - pavg_r2r (mm3, mm2); - por_r2r (mm6, mm7); - movq_r2r (mm0, mm6); - pxor_r2r (mm2, mm6); - pand_r2r (mm6, mm7); - pand_m2r (mask_one, mm7); - pavg_r2r (mm2, mm0); - psubusb_r2r (mm7, mm0); - ref += stride; - movq_r2m (mm0, *(dest+8)); - dest += stride; - } while (--height); -} - -static inline void MC_avg4_8 (int height, uint8_t * dest, uint8_t * ref, - int stride, int cpu) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+stride+1), mm1); - movq_r2r (mm0, mm7); - movq_m2r (*(ref+1), mm2); - pxor_r2r (mm1, mm7); - movq_m2r (*(ref+stride), mm3); - movq_r2r (mm2, mm6); - pxor_r2r (mm3, mm6); - pavg_r2r (mm1, mm0); - pavg_r2r (mm3, mm2); - por_r2r (mm6, mm7); - movq_r2r (mm0, mm6); - pxor_r2r (mm2, mm6); - pand_r2r (mm6, mm7); - pand_m2r (mask_one, mm7); - pavg_r2r (mm2, mm0); - psubusb_r2r (mm7, mm0); - movq_m2r (*dest, mm1); - pavg_r2r (mm1, mm0); - ref += stride; - movq_r2m (mm0, *dest); - dest += stride; - } while (--height); -} - -static inline void MC_avg4_16 (int height, uint8_t * dest, uint8_t * ref, - int stride, int cpu) -{ - do { - movq_m2r (*ref, mm0); - movq_m2r (*(ref+stride+1), mm1); - movq_r2r (mm0, mm7); - movq_m2r (*(ref+1), mm2); - pxor_r2r (mm1, mm7); - movq_m2r (*(ref+stride), mm3); - movq_r2r (mm2, mm6); - pxor_r2r (mm3, mm6); - pavg_r2r (mm1, mm0); - pavg_r2r (mm3, mm2); - por_r2r (mm6, mm7); - movq_r2r (mm0, mm6); - pxor_r2r (mm2, mm6); - pand_r2r (mm6, mm7); - pand_m2r (mask_one, mm7); - pavg_r2r (mm2, mm0); - psubusb_r2r (mm7, mm0); - movq_m2r (*dest, mm1); - pavg_r2r (mm1, mm0); - movq_r2m (mm0, *dest); - - movq_m2r (*(ref+8), mm0); - movq_m2r (*(ref+stride+9), mm1); - movq_r2r (mm0, mm7); - movq_m2r (*(ref+9), mm2); - pxor_r2r (mm1, mm7); - movq_m2r (*(ref+stride+8), mm3); - movq_r2r (mm2, mm6); - pxor_r2r (mm3, mm6); - pavg_r2r (mm1, mm0); - pavg_r2r (mm3, mm2); - por_r2r (mm6, mm7); - movq_r2r (mm0, mm6); - pxor_r2r (mm2, mm6); - pand_r2r (mm6, mm7); - pand_m2r (mask_one, mm7); - pavg_r2r (mm2, mm0); - psubusb_r2r (mm7, mm0); - movq_m2r (*(dest+8), mm1); - pavg_r2r (mm1, mm0); - ref += stride; - movq_r2m (mm0, *(dest+8)); - dest += stride; - } while (--height); -} - -static void MC_avg_o_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); -} - -static void MC_avg_o_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); -} - -static void MC_put_o_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put1_16 (height, dest, ref, stride); -} - -static void MC_put_o_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put1_8 (height, dest, ref, stride); -} - -static void MC_avg_x_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); -} - -static void MC_avg_x_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); -} - -static void MC_put_x_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); -} - -static void MC_put_x_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); -} - -static void MC_avg_y_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); -} - -static void MC_avg_y_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); -} - -static void MC_put_y_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); -} - -static void MC_put_y_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); -} - -static void MC_avg_xy_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); -} - -static void MC_avg_xy_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); -} - -static void MC_put_xy_16_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); -} - -static void MC_put_xy_8_mmxext (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); -} - - -MPEG2_MC_EXTERN (mmxext) - - - -static void MC_avg_o_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); -} - -static void MC_avg_o_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); -} - -static void MC_put_o_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put1_16 (height, dest, ref, stride); -} - -static void MC_put_o_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put1_8 (height, dest, ref, stride); -} - -static void MC_avg_x_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); -} - -static void MC_avg_x_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); -} - -static void MC_put_x_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); -} - -static void MC_put_x_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); -} - -static void MC_avg_y_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); -} - -static void MC_avg_y_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); -} - -static void MC_put_y_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); -} - -static void MC_put_y_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); -} - -static void MC_avg_xy_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); -} - -static void MC_avg_xy_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); -} - -static void MC_put_xy_16_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); -} - -static void MC_put_xy_8_3dnow (uint8_t * dest, uint8_t * ref, - int stride, int height) -{ - MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); -} - - -MPEG2_MC_EXTERN (3dnow) - -#endif diff --git a/src/libmpeg2/motion_comp_vis.c b/src/libmpeg2/motion_comp_vis.c deleted file mode 100644 index d0a6673d6..000000000 --- a/src/libmpeg2/motion_comp_vis.c +++ /dev/null @@ -1,2059 +0,0 @@ -/* - * motion_comp_vis.c - * Copyright (C) 2003 David S. Miller - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#if defined(ARCH_SPARC) && defined(ENABLE_VIS) - -#include - -#include "mpeg2_internal.h" -#include "vis.h" - -/* The trick used in some of this file is the formula from the MMX - * motion comp code, which is: - * - * (x+y+1)>>1 == (x|y)-((x^y)>>1) - * - * This allows us to average 8 bytes at a time in a 64-bit FPU reg. - * We avoid overflows by masking before we do the shift, and we - * implement the shift by multiplying by 1/2 using mul8x16. So in - * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask - * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and - * the value 0x80808080 is in f8): - * - * fxor f0, f2, f10 - * fand f10, f4, f10 - * fmul8x16 f8, f10, f10 - * fand f10, f6, f10 - * for f0, f2, f12 - * fpsub16 f12, f10, f10 - */ - -#define DUP4(x) {x, x, x, x} -#define DUP8(x) {x, x, x, x, x, x, x, x} -static const int16_t constants1[] ATTR_ALIGN(8) = DUP4 (1); -static const int16_t constants2[] ATTR_ALIGN(8) = DUP4 (2); -static const int16_t constants3[] ATTR_ALIGN(8) = DUP4 (3); -static const int16_t constants6[] ATTR_ALIGN(8) = DUP4 (6); -static const int8_t constants_fe[] ATTR_ALIGN(8) = DUP8 (0xfe); -static const int8_t constants_7f[] ATTR_ALIGN(8) = DUP8 (0x7f); -static const int8_t constants128[] ATTR_ALIGN(8) = DUP8 (128); -static const int16_t constants256_512[] ATTR_ALIGN(8) = - {256, 512, 256, 512}; -static const int16_t constants256_1024[] ATTR_ALIGN(8) = - {256, 1024, 256, 1024}; - -#define REF_0 0 -#define REF_0_1 1 -#define REF_2 2 -#define REF_2_1 3 -#define REF_4 4 -#define REF_4_1 5 -#define REF_6 6 -#define REF_6_1 7 -#define REF_S0 8 -#define REF_S0_1 9 -#define REF_S2 10 -#define REF_S2_1 11 -#define REF_S4 12 -#define REF_S4_1 13 -#define REF_S6 14 -#define REF_S6_1 15 -#define DST_0 16 -#define DST_1 17 -#define DST_2 18 -#define DST_3 19 -#define CONST_1 20 -#define CONST_2 20 -#define CONST_3 20 -#define CONST_6 20 -#define MASK_fe 20 -#define CONST_128 22 -#define CONST_256 22 -#define CONST_512 22 -#define CONST_1024 22 -#define TMP0 24 -#define TMP1 25 -#define TMP2 26 -#define TMP3 27 -#define TMP4 28 -#define TMP5 29 -#define ZERO 30 -#define MASK_7f 30 - -#define TMP6 32 -#define TMP8 34 -#define TMP10 36 -#define TMP12 38 -#define TMP14 40 -#define TMP16 42 -#define TMP18 44 -#define TMP20 46 -#define TMP22 48 -#define TMP24 50 -#define TMP26 52 -#define TMP28 54 -#define TMP30 56 -#define TMP32 58 - -static void MC_put_o_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int offset; - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 16 : 0; - do { /* 5 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, offset, TMP4); - ref += stride; - - vis_faligndata(TMP0, TMP2, REF_0); - vis_st64(REF_0, dest[0]); - - vis_faligndata(TMP2, TMP4, REF_2); - vis_st64_2(REF_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_put_o_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int offset; - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 8 : 0; - do { /* 4 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, offset, TMP2); - ref += stride; - - /* stall */ - - vis_faligndata(TMP0, TMP2, REF_0); - vis_st64(REF_0, dest[0]); - dest += stride; - } while (--height); -} - - -static void MC_avg_o_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int stride_8 = stride + 8; - int offset; - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 16 : 0; - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64_2(ref, offset, TMP4); - - vis_ld64(dest[0], DST_0); - - vis_ld64(dest[8], DST_2); - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP2, TMP4, REF_2); - - vis_ld64(constants128[0], CONST_128); - - ref += stride; - height = (height >> 1) - 1; - - do { /* 24 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP6, MASK_fe, TMP6); - - vis_ld64_2(ref, offset, TMP4); - ref += stride; - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_xor(DST_2, REF_2, TMP8); - - vis_and(TMP8, MASK_fe, TMP8); - - vis_or(DST_0, REF_0, TMP10); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP8, TMP8); - - vis_or(DST_2, REF_2, TMP12); - vis_ld64_2(dest, stride_8, DST_2); - - vis_ld64(ref[0], TMP14); - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - - dest += stride; - vis_ld64_2(ref, 8, TMP16); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, offset, TMP18); - vis_faligndata(TMP2, TMP4, REF_2); - ref += stride; - - vis_xor(DST_0, REF_0, TMP20); - - vis_and(TMP20, MASK_fe, TMP20); - - vis_xor(DST_2, REF_2, TMP22); - vis_mul8x16(CONST_128, TMP20, TMP20); - - vis_and(TMP22, MASK_fe, TMP22); - - vis_or(DST_0, REF_0, TMP24); - vis_mul8x16(CONST_128, TMP22, TMP22); - - vis_or(DST_2, REF_2, TMP26); - - vis_ld64_2(dest, stride, DST_0); - vis_faligndata(TMP14, TMP16, REF_0); - - vis_ld64_2(dest, stride_8, DST_2); - vis_faligndata(TMP16, TMP18, REF_2); - - vis_and(TMP20, MASK_7f, TMP20); - - vis_and(TMP22, MASK_7f, TMP22); - - vis_psub16(TMP24, TMP20, TMP20); - vis_st64(TMP20, dest[0]); - - vis_psub16(TMP26, TMP22, TMP22); - vis_st64_2(TMP22, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP6, MASK_fe, TMP6); - - vis_ld64_2(ref, offset, TMP4); - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_xor(DST_2, REF_2, TMP8); - - vis_and(TMP8, MASK_fe, TMP8); - - vis_or(DST_0, REF_0, TMP10); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP8, TMP8); - - vis_or(DST_2, REF_2, TMP12); - vis_ld64_2(dest, stride_8, DST_2); - - vis_ld64(ref[0], TMP14); - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - - dest += stride; - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_2); - - vis_xor(DST_0, REF_0, TMP20); - - vis_and(TMP20, MASK_fe, TMP20); - - vis_xor(DST_2, REF_2, TMP22); - vis_mul8x16(CONST_128, TMP20, TMP20); - - vis_and(TMP22, MASK_fe, TMP22); - - vis_or(DST_0, REF_0, TMP24); - vis_mul8x16(CONST_128, TMP22, TMP22); - - vis_or(DST_2, REF_2, TMP26); - - vis_and(TMP20, MASK_7f, TMP20); - - vis_and(TMP22, MASK_7f, TMP22); - - vis_psub16(TMP24, TMP20, TMP20); - vis_st64(TMP20, dest[0]); - - vis_psub16(TMP26, TMP22, TMP22); - vis_st64_2(TMP22, dest, 8); -} - -static void MC_avg_o_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int offset; - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 8 : 0; - - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, offset, TMP2); - - vis_ld64(dest[0], DST_0); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants128[0], CONST_128); - - ref += stride; - height = (height >> 1) - 1; - - do { /* 12 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP4); - - vis_ld64_2(ref, offset, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - ref += stride; - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_ld64(ref[0], TMP12); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, offset, TMP2); - vis_xor(DST_0, REF_0, TMP0); - ref += stride; - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_or(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - - vis_faligndata(TMP12, TMP2, REF_0); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_psub16(TMP6, TMP0, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP4); - - vis_ld64_2(ref, offset, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_xor(DST_0, REF_0, TMP0); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_or(DST_0, REF_0, TMP6); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_psub16(TMP6, TMP0, TMP4); - vis_st64(TMP4, dest[0]); -} - -static void MC_put_x_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants128[0], CONST_128); - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - ref += stride; - height = (height >> 1) - 1; - - do { /* 34 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP8); - - vis_ld64_2(ref, 16, TMP4); - vis_and(TMP6, MASK_fe, TMP6); - ref += stride; - - vis_ld64(ref[0], TMP14); - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_ld64_2(ref, 8, TMP16); - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_ld64_2(ref, 16, TMP18); - ref += stride; - vis_or(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - - vis_xor(REF_0, REF_2, TMP6); - - vis_xor(REF_4, REF_6, TMP8); - - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_or(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP14, TMP16, REF_0); - - vis_faligndata(TMP16, TMP18, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP14, TMP16, REF_2); - vis_faligndata(TMP16, TMP18, REF_6); - } else { - vis_src1(TMP16, REF_2); - vis_src1(TMP18, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP8); - - vis_ld64_2(ref, 16, TMP4); - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_or(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - - vis_xor(REF_0, REF_2, TMP6); - - vis_xor(REF_4, REF_6, TMP8); - - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_or(REF_4, REF_6, TMP12); - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); -} - -static void MC_put_x_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - - vis_ld64(constants128[0], CONST_128); - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - ref += stride; - height = (height >> 1) - 1; - - do { /* 20 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - ref += stride; - - vis_ld64(ref[0], TMP8); - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, 8, TMP10); - ref += stride; - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_or(REF_0, REF_2, TMP14); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_alignaddr_g0((void *)off); - vis_faligndata(TMP8, TMP10, REF_0); - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP8, TMP10, REF_2); - } else { - vis_src1(TMP10, REF_2); - } - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_or(REF_0, REF_2, TMP14); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; -} - -static void MC_avg_x_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - vis_ld64(constants3[0], CONST_3); - vis_fzero(ZERO); - vis_ld64(constants256_512[0], CONST_256); - - ref = vis_alignaddr(ref); - do { /* 26 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_alignaddr_g0((void *)off); - - vis_ld64(ref[16], TMP4); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(dest[8], DST_2); - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_mul8x16au(REF_0, CONST_256, TMP0); - - vis_pmerge(ZERO, REF_2, TMP4); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_mul8x16al(DST_0, CONST_512, TMP4); - vis_padd16(TMP2, TMP6, TMP2); - - vis_mul8x16al(DST_1, CONST_512, TMP6); - - vis_mul8x16au(REF_6, CONST_256, TMP12); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_6_1, CONST_256, TMP14); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4, CONST_256, TMP16); - - vis_padd16(TMP0, CONST_3, TMP8); - vis_mul8x16au(REF_4_1, CONST_256, TMP18); - - vis_padd16(TMP2, CONST_3, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_padd16(TMP16, TMP12, TMP0); - - vis_st64(DST_0, dest[0]); - vis_mul8x16al(DST_2, CONST_512, TMP4); - vis_padd16(TMP18, TMP14, TMP2); - - vis_mul8x16al(DST_3, CONST_512, TMP6); - vis_padd16(TMP0, CONST_3, TMP0); - - vis_padd16(TMP2, CONST_3, TMP2); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_padd16(TMP2, TMP6, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64(DST_2, dest[8]); - - ref += stride; - dest += stride; - } while (--height); -} - -static void MC_avg_x_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_times_2 = stride << 1; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - vis_ld64(constants3[0], CONST_3); - vis_fzero(ZERO); - vis_ld64(constants256_512[0], CONST_256); - - ref = vis_alignaddr(ref); - height >>= 2; - do { /* 47 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - - vis_alignaddr_g0((void *)off); - - vis_ld64(ref[0], TMP4); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 8, TMP6); - ref += stride; - - vis_ld64(ref[0], TMP8); - - vis_ld64_2(ref, 8, TMP10); - ref += stride; - vis_faligndata(TMP4, TMP6, REF_4); - - vis_ld64(ref[0], TMP12); - - vis_ld64_2(ref, 8, TMP14); - ref += stride; - vis_faligndata(TMP8, TMP10, REF_S0); - - vis_faligndata(TMP12, TMP14, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64_2(dest, stride, DST_2); - vis_faligndata(TMP4, TMP6, REF_6); - - vis_faligndata(TMP8, TMP10, REF_S2); - - vis_faligndata(TMP12, TMP14, REF_S6); - } else { - vis_ld64(dest[0], DST_0); - vis_src1(TMP2, REF_2); - - vis_ld64_2(dest, stride, DST_2); - vis_src1(TMP6, REF_6); - - vis_src1(TMP10, REF_S2); - - vis_src1(TMP14, REF_S6); - } - - vis_pmerge(ZERO, REF_0, TMP0); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_pmerge(ZERO, REF_2, TMP4); - vis_mul8x16au(REF_2_1, CONST_256, TMP6); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16al(DST_0, CONST_512, TMP16); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16al(DST_1, CONST_512, TMP18); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_4, CONST_256, TMP8); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4_1, CONST_256, TMP10); - - vis_padd16(TMP0, TMP16, TMP0); - vis_mul8x16au(REF_6, CONST_256, TMP12); - - vis_padd16(TMP2, TMP18, TMP2); - vis_mul8x16au(REF_6_1, CONST_256, TMP14); - - vis_padd16(TMP8, CONST_3, TMP8); - vis_mul8x16al(DST_2, CONST_512, TMP16); - - vis_padd16(TMP8, TMP12, TMP8); - vis_mul8x16al(DST_3, CONST_512, TMP18); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP0, DST_0); - - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP10, CONST_3, TMP10); - - vis_ld64_2(dest, stride, DST_0); - vis_padd16(TMP8, TMP16, TMP8); - - vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/); - vis_padd16(TMP10, TMP18, TMP10); - vis_pack16(TMP8, DST_2); - - vis_pack16(TMP10, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - - vis_mul8x16au(REF_S0_1, CONST_256, TMP2); - vis_pmerge(ZERO, REF_S0, TMP0); - - vis_pmerge(ZERO, REF_S2, TMP24); - vis_mul8x16au(REF_S2_1, CONST_256, TMP6); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16au(REF_S4, CONST_256, TMP8); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16au(REF_S4_1, CONST_256, TMP10); - - vis_padd16(TMP0, TMP24, TMP0); - vis_mul8x16au(REF_S6, CONST_256, TMP12); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_S6_1, CONST_256, TMP14); - - vis_padd16(TMP8, CONST_3, TMP8); - vis_mul8x16al(DST_0, CONST_512, TMP16); - - vis_padd16(TMP10, CONST_3, TMP10); - vis_mul8x16al(DST_1, CONST_512, TMP18); - - vis_padd16(TMP8, TMP12, TMP8); - vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20); - - vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22); - vis_padd16(TMP0, TMP16, TMP0); - - vis_padd16(TMP2, TMP18, TMP2); - vis_pack16(TMP0, DST_0); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_padd16(TMP8, TMP20, TMP8); - - vis_padd16(TMP10, TMP22, TMP10); - vis_pack16(TMP8, DST_2); - - vis_pack16(TMP10, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_put_y_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int offset; - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 16 : 0; - - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, offset, TMP4); - ref += stride; - - vis_ld64(ref[0], TMP6); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 8, TMP8); - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64_2(ref, offset, TMP10); - ref += stride; - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP6, TMP8, REF_2); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP8, TMP10, REF_6); - - vis_ld64(constants128[0], CONST_128); - height = (height >> 1) - 1; - do { /* 24 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP12); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP16); - - vis_ld64_2(ref, offset, TMP4); - ref += stride; - vis_or(REF_0, REF_2, TMP14); - - vis_ld64(ref[0], TMP6); - vis_or(REF_4, REF_6, TMP18); - - vis_ld64_2(ref, 8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, offset, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(TMP16, MASK_fe, TMP16); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_mul8x16(CONST_128, TMP16, TMP16); - vis_xor(REF_0, REF_2, TMP0); - - vis_xor(REF_4, REF_6, TMP2); - - vis_or(REF_0, REF_2, TMP20); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_and(TMP16, MASK_7f, TMP16); - - vis_psub16(TMP14, TMP12, TMP12); - vis_st64(TMP12, dest[0]); - - vis_psub16(TMP18, TMP16, TMP16); - vis_st64_2(TMP16, dest, 8); - dest += stride; - - vis_or(REF_4, REF_6, TMP18); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP2, MASK_fe, TMP2); - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_faligndata(TMP6, TMP8, REF_2); - vis_mul8x16(CONST_128, TMP2, TMP2); - - vis_faligndata(TMP8, TMP10, REF_6); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_and(TMP2, MASK_7f, TMP2); - - vis_psub16(TMP20, TMP0, TMP0); - vis_st64(TMP0, dest[0]); - - vis_psub16(TMP18, TMP2, TMP2); - vis_st64_2(TMP2, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP12); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP16); - - vis_ld64_2(ref, offset, TMP4); - vis_or(REF_0, REF_2, TMP14); - - vis_or(REF_4, REF_6, TMP18); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(TMP16, MASK_fe, TMP16); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_mul8x16(CONST_128, TMP16, TMP16); - vis_xor(REF_0, REF_2, TMP0); - - vis_xor(REF_4, REF_6, TMP2); - - vis_or(REF_0, REF_2, TMP20); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_and(TMP16, MASK_7f, TMP16); - - vis_psub16(TMP14, TMP12, TMP12); - vis_st64(TMP12, dest[0]); - - vis_psub16(TMP18, TMP16, TMP16); - vis_st64_2(TMP16, dest, 8); - dest += stride; - - vis_or(REF_4, REF_6, TMP18); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP2, MASK_fe, TMP2); - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_mul8x16(CONST_128, TMP2, TMP2); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_and(TMP2, MASK_7f, TMP2); - - vis_psub16(TMP20, TMP0, TMP0); - vis_st64(TMP0, dest[0]); - - vis_psub16(TMP18, TMP2, TMP2); - vis_st64_2(TMP2, dest, 8); -} - -static void MC_put_y_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int offset; - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 8 : 0; - - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, offset, TMP2); - ref += stride; - - vis_ld64(ref[0], TMP4); - - vis_ld64_2(ref, offset, TMP6); - ref += stride; - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP4, TMP6, REF_2); - - vis_ld64(constants128[0], CONST_128); - height = (height >> 1) - 1; - do { /* 12 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, offset, TMP2); - ref += stride; - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, offset, TMP2); - ref += stride; - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_mul8x16(CONST_128, TMP12, TMP12); - vis_or(REF_0, REF_2, TMP14); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_faligndata(TMP0, TMP2, REF_2); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, offset, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_mul8x16(CONST_128, TMP12, TMP12); - vis_or(REF_0, REF_2, TMP14); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); -} - -static void MC_avg_y_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int stride_8 = stride + 8; - int stride_16; - int offset; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 16 : 0; - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64_2(ref, offset, TMP4); - stride_16 = stride + offset; - - vis_ld64(constants3[0], CONST_3); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_6); - height >>= 1; - - do { /* 31 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_pmerge(ZERO, REF_2, TMP12); - vis_mul8x16au(REF_2_1, CONST_256, TMP14); - - vis_ld64_2(ref, stride_8, TMP2); - vis_pmerge(ZERO, REF_6, TMP16); - vis_mul8x16au(REF_6_1, CONST_256, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(dest, 8, DST_2); - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64_2(ref, stride, TMP6); - vis_pmerge(ZERO, REF_0, TMP0); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_ld64_2(ref, stride_8, TMP8); - vis_pmerge(ZERO, REF_4, TMP4); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - - vis_ld64_2(dest, stride, REF_S0/*DST_4*/); - vis_faligndata(TMP6, TMP8, REF_2); - vis_mul8x16au(REF_4_1, CONST_256, TMP6); - - vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/); - vis_faligndata(TMP8, TMP10, REF_6); - vis_mul8x16al(DST_0, CONST_512, TMP20); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16al(DST_1, CONST_512, TMP22); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16al(DST_2, CONST_512, TMP24); - - vis_padd16(TMP4, CONST_3, TMP4); - vis_mul8x16al(DST_3, CONST_512, TMP26); - - vis_padd16(TMP6, CONST_3, TMP6); - - vis_padd16(TMP12, TMP20, TMP12); - vis_mul8x16al(REF_S0, CONST_512, TMP20); - - vis_padd16(TMP14, TMP22, TMP14); - vis_mul8x16al(REF_S0_1, CONST_512, TMP22); - - vis_padd16(TMP16, TMP24, TMP16); - vis_mul8x16al(REF_S2, CONST_512, TMP24); - - vis_padd16(TMP18, TMP26, TMP18); - vis_mul8x16al(REF_S2_1, CONST_512, TMP26); - - vis_padd16(TMP12, TMP0, TMP12); - vis_mul8x16au(REF_2, CONST_256, TMP28); - - vis_padd16(TMP14, TMP2, TMP14); - vis_mul8x16au(REF_2_1, CONST_256, TMP30); - - vis_padd16(TMP16, TMP4, TMP16); - vis_mul8x16au(REF_6, CONST_256, REF_S4); - - vis_padd16(TMP18, TMP6, TMP18); - vis_mul8x16au(REF_6_1, CONST_256, REF_S6); - - vis_pack16(TMP12, DST_0); - vis_padd16(TMP28, TMP0, TMP12); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP30, TMP2, TMP14); - - vis_pack16(TMP16, DST_2); - vis_padd16(REF_S4, TMP4, TMP16); - - vis_pack16(TMP18, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - vis_padd16(REF_S6, TMP6, TMP18); - - vis_padd16(TMP12, TMP20, TMP12); - - vis_padd16(TMP14, TMP22, TMP14); - vis_pack16(TMP12, DST_0); - - vis_padd16(TMP16, TMP24, TMP16); - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - - vis_padd16(TMP18, TMP26, TMP18); - vis_pack16(TMP16, DST_2); - - vis_pack16(TMP18, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_avg_y_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - int stride_8; - int offset; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - offset = (ref != _ref) ? 8 : 0; - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64_2(ref, offset, TMP2); - stride_8 = stride + offset; - - vis_ld64(constants3[0], CONST_3); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64(constants256_512[0], CONST_256); - - height >>= 1; - do { /* 20 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_pmerge(ZERO, REF_2, TMP8); - vis_mul8x16au(REF_2_1, CONST_256, TMP10); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - - vis_ld64(dest[0], DST_0); - - vis_ld64_2(dest, stride, DST_2); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride, TMP4); - vis_mul8x16al(DST_0, CONST_512, TMP16); - vis_pmerge(ZERO, REF_0, TMP12); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - vis_mul8x16al(DST_1, CONST_512, TMP18); - vis_pmerge(ZERO, REF_0_1, TMP14); - - vis_padd16(TMP12, CONST_3, TMP12); - vis_mul8x16al(DST_2, CONST_512, TMP24); - - vis_padd16(TMP14, CONST_3, TMP14); - vis_mul8x16al(DST_3, CONST_512, TMP26); - - vis_faligndata(TMP4, TMP6, REF_2); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - vis_mul8x16au(REF_2, CONST_256, TMP20); - - vis_padd16(TMP8, TMP16, TMP0); - vis_mul8x16au(REF_2_1, CONST_256, TMP22); - - vis_padd16(TMP10, TMP18, TMP2); - vis_pack16(TMP0, DST_0); - - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP12, TMP20, TMP12); - - vis_padd16(TMP14, TMP22, TMP14); - - vis_padd16(TMP12, TMP24, TMP0); - - vis_padd16(TMP14, TMP26, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_put_xy_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants2[0], CONST_2); - vis_faligndata(TMP0, TMP2, REF_S0); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - vis_faligndata(TMP2, TMP4, REF_S6); - } else { - vis_src1(TMP2, REF_S2); - vis_src1(TMP4, REF_S6); - } - - height >>= 1; - do { - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S0_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - vis_mul8x16au(REF_S2, CONST_256, TMP16); - vis_pmerge(ZERO, REF_S2_1, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - vis_mul8x16au(REF_S4, CONST_256, TMP20); - vis_pmerge(ZERO, REF_S4_1, TMP22); - - vis_ld64_2(ref, stride, TMP6); - vis_mul8x16au(REF_S6, CONST_256, TMP24); - vis_pmerge(ZERO, REF_S6_1, TMP26); - - vis_ld64_2(ref, stride_8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_faligndata(TMP6, TMP8, REF_S0); - - vis_faligndata(TMP8, TMP10, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - vis_faligndata(TMP6, TMP8, REF_S2); - vis_faligndata(TMP8, TMP10, REF_S6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - vis_src1(TMP8, REF_S2); - vis_src1(TMP10, REF_S6); - } - - vis_mul8x16au(REF_0, CONST_256, TMP0); - vis_pmerge(ZERO, REF_0_1, TMP2); - - vis_mul8x16au(REF_2, CONST_256, TMP4); - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_padd16(TMP0, CONST_2, TMP8); - vis_mul8x16au(REF_4, CONST_256, TMP0); - - vis_padd16(TMP2, CONST_2, TMP10); - vis_mul8x16au(REF_4_1, CONST_256, TMP2); - - vis_padd16(TMP8, TMP4, TMP8); - vis_mul8x16au(REF_6, CONST_256, TMP4); - - vis_padd16(TMP10, TMP6, TMP10); - vis_mul8x16au(REF_6_1, CONST_256, TMP6); - - vis_padd16(TMP12, TMP8, TMP12); - - vis_padd16(TMP14, TMP10, TMP14); - - vis_padd16(TMP12, TMP16, TMP12); - - vis_padd16(TMP14, TMP18, TMP14); - vis_pack16(TMP12, DST_0); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP0, CONST_2, TMP12); - - vis_mul8x16au(REF_S0, CONST_256, TMP0); - vis_padd16(TMP2, CONST_2, TMP14); - - vis_mul8x16au(REF_S0_1, CONST_256, TMP2); - vis_padd16(TMP12, TMP4, TMP12); - - vis_mul8x16au(REF_S2, CONST_256, TMP4); - vis_padd16(TMP14, TMP6, TMP14); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP6); - vis_padd16(TMP20, TMP12, TMP20); - - vis_padd16(TMP22, TMP14, TMP22); - - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP22, TMP26, TMP22); - vis_pack16(TMP20, DST_2); - - vis_pack16(TMP22, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - vis_padd16(TMP0, TMP4, TMP24); - - vis_mul8x16au(REF_S4, CONST_256, TMP0); - vis_padd16(TMP2, TMP6, TMP26); - - vis_mul8x16au(REF_S4_1, CONST_256, TMP2); - vis_padd16(TMP24, TMP8, TMP24); - - vis_padd16(TMP26, TMP10, TMP26); - vis_pack16(TMP24, DST_0); - - vis_pack16(TMP26, DST_1); - vis_st64(DST_0, dest[0]); - vis_pmerge(ZERO, REF_S6, TMP4); - - vis_pmerge(ZERO, REF_S6_1, TMP6); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_padd16(TMP2, TMP6, TMP2); - - vis_padd16(TMP0, TMP12, TMP0); - - vis_padd16(TMP2, TMP14, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_put_xy_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(constants2[0], CONST_2); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP0, TMP2, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - } else { - vis_src1(TMP2, REF_S2); - } - - height >>= 1; - do { /* 26 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP8); - vis_pmerge(ZERO, REF_S2, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - vis_mul8x16au(REF_S0_1, CONST_256, TMP10); - vis_pmerge(ZERO, REF_S2_1, TMP14); - - vis_ld64_2(ref, stride, TMP4); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - vis_faligndata(TMP0, TMP2, REF_S4); - - vis_pmerge(ZERO, REF_S4, TMP18); - - vis_pmerge(ZERO, REF_S4_1, TMP20); - - vis_faligndata(TMP4, TMP6, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S6); - vis_faligndata(TMP4, TMP6, REF_S2); - } else { - vis_src1(TMP2, REF_S6); - vis_src1(TMP6, REF_S2); - } - - vis_padd16(TMP18, CONST_2, TMP18); - vis_mul8x16au(REF_S6, CONST_256, TMP22); - - vis_padd16(TMP20, CONST_2, TMP20); - vis_mul8x16au(REF_S6_1, CONST_256, TMP24); - - vis_mul8x16au(REF_S0, CONST_256, TMP26); - vis_pmerge(ZERO, REF_S0_1, TMP28); - - vis_mul8x16au(REF_S2, CONST_256, TMP30); - vis_padd16(TMP18, TMP22, TMP18); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP32); - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP8, TMP18, TMP8); - - vis_padd16(TMP10, TMP20, TMP10); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP18, TMP26, TMP18); - - vis_padd16(TMP20, TMP28, TMP20); - - vis_padd16(TMP18, TMP30, TMP18); - - vis_padd16(TMP20, TMP32, TMP20); - vis_pack16(TMP18, DST_2); - - vis_pack16(TMP20, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_avg_xy_16_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants6[0], CONST_6); - vis_faligndata(TMP0, TMP2, REF_S0); - - vis_ld64(constants256_1024[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - vis_faligndata(TMP2, TMP4, REF_S6); - } else { - vis_src1(TMP2, REF_S2); - vis_src1(TMP4, REF_S6); - } - - height >>= 1; - do { /* 55 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S0_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - vis_mul8x16au(REF_S2, CONST_256, TMP16); - vis_pmerge(ZERO, REF_S2_1, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - vis_mul8x16au(REF_S4, CONST_256, TMP20); - vis_pmerge(ZERO, REF_S4_1, TMP22); - - vis_ld64_2(ref, stride, TMP6); - vis_mul8x16au(REF_S6, CONST_256, TMP24); - vis_pmerge(ZERO, REF_S6_1, TMP26); - - vis_ld64_2(ref, stride_8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP6, TMP8, REF_S0); - - vis_ld64_2(dest, 8, DST_2); - vis_faligndata(TMP8, TMP10, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - vis_faligndata(TMP6, TMP8, REF_S2); - vis_faligndata(TMP8, TMP10, REF_S6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - vis_src1(TMP8, REF_S2); - vis_src1(TMP10, REF_S6); - } - - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_0, TMP0); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_pmerge(ZERO, REF_0_1, TMP2); - - vis_mul8x16au(REF_2, CONST_256, TMP4); - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_mul8x16al(DST_2, CONST_1024, REF_0); - vis_padd16(TMP0, CONST_6, TMP0); - - vis_mul8x16al(DST_3, CONST_1024, REF_2); - vis_padd16(TMP2, CONST_6, TMP2); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_4, CONST_256, TMP4); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4_1, CONST_256, TMP6); - - vis_padd16(TMP12, TMP0, TMP12); - vis_mul8x16au(REF_6, CONST_256, TMP8); - - vis_padd16(TMP14, TMP2, TMP14); - vis_mul8x16au(REF_6_1, CONST_256, TMP10); - - vis_padd16(TMP12, TMP16, TMP12); - vis_mul8x16au(REF_S0, CONST_256, REF_4); - - vis_padd16(TMP14, TMP18, TMP14); - vis_mul8x16au(REF_S0_1, CONST_256, REF_6); - - vis_padd16(TMP12, TMP30, TMP12); - - vis_padd16(TMP14, TMP32, TMP14); - vis_pack16(TMP12, DST_0); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP4, CONST_6, TMP4); - - vis_ld64_2(dest, stride, DST_0); - vis_padd16(TMP6, CONST_6, TMP6); - vis_mul8x16au(REF_S2, CONST_256, TMP12); - - vis_padd16(TMP4, TMP8, TMP4); - vis_mul8x16au(REF_S2_1, CONST_256, TMP14); - - vis_padd16(TMP6, TMP10, TMP6); - - vis_padd16(TMP20, TMP4, TMP20); - - vis_padd16(TMP22, TMP6, TMP22); - - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP22, TMP26, TMP22); - - vis_padd16(TMP20, REF_0, TMP20); - vis_mul8x16au(REF_S4, CONST_256, REF_0); - - vis_padd16(TMP22, REF_2, TMP22); - vis_pack16(TMP20, DST_2); - - vis_pack16(TMP22, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - - vis_ld64_2(dest, 8, DST_2); - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_S4_1, REF_2); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_padd16(REF_4, TMP0, TMP8); - - vis_mul8x16au(REF_S6, CONST_256, REF_4); - vis_padd16(REF_6, TMP2, TMP10); - - vis_mul8x16au(REF_S6_1, CONST_256, REF_6); - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - - vis_padd16(TMP8, TMP30, TMP8); - - vis_padd16(TMP10, TMP32, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - - vis_padd16(REF_0, TMP4, REF_0); - - vis_mul8x16al(DST_2, CONST_1024, TMP30); - vis_padd16(REF_2, TMP6, REF_2); - - vis_mul8x16al(DST_3, CONST_1024, TMP32); - vis_padd16(REF_0, REF_4, REF_0); - - vis_padd16(REF_2, REF_6, REF_2); - - vis_padd16(REF_0, TMP30, REF_0); - - /* stall */ - - vis_padd16(REF_2, TMP32, REF_2); - vis_pack16(REF_0, DST_2); - - vis_pack16(REF_2, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_avg_xy_8_vis (uint8_t * dest, uint8_t * _ref, - int stride, int height) -{ - uint8_t *ref = (uint8_t *) _ref; - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - - vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - vis_fzero(ZERO); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64(constants6[0], CONST_6); - - vis_ld64(constants256_1024[0], CONST_256); - vis_faligndata(TMP0, TMP2, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - } else { - vis_src1(TMP2, REF_S2); - } - - height >>= 1; - do { /* 31 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP8); - vis_pmerge(ZERO, REF_S0_1, TMP10); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - vis_mul8x16au(REF_S2, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S2_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride, TMP4); - vis_faligndata(TMP0, TMP2, REF_S4); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP4, TMP6, REF_S0); - - vis_ld64_2(dest, stride, DST_2); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S6); - vis_faligndata(TMP4, TMP6, REF_S2); - } else { - vis_src1(TMP2, REF_S6); - vis_src1(TMP6, REF_S2); - } - - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_S4, TMP22); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_pmerge(ZERO, REF_S4_1, TMP24); - - vis_mul8x16au(REF_S6, CONST_256, TMP26); - vis_pmerge(ZERO, REF_S6_1, TMP28); - - vis_mul8x16au(REF_S0, CONST_256, REF_S4); - vis_padd16(TMP22, CONST_6, TMP22); - - vis_mul8x16au(REF_S0_1, CONST_256, REF_S6); - vis_padd16(TMP24, CONST_6, TMP24); - - vis_mul8x16al(DST_2, CONST_1024, REF_0); - vis_padd16(TMP22, TMP26, TMP22); - - vis_mul8x16al(DST_3, CONST_1024, REF_2); - vis_padd16(TMP24, TMP28, TMP24); - - vis_mul8x16au(REF_S2, CONST_256, TMP26); - vis_padd16(TMP8, TMP22, TMP8); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP28); - vis_padd16(TMP10, TMP24, TMP10); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - - vis_padd16(TMP8, TMP30, TMP8); - - vis_padd16(TMP10, TMP32, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_padd16(REF_S4, TMP22, TMP12); - - vis_padd16(REF_S6, TMP24, TMP14); - - vis_padd16(TMP12, TMP26, TMP12); - - vis_padd16(TMP14, TMP28, TMP14); - - vis_padd16(TMP12, REF_0, TMP12); - - vis_padd16(TMP14, REF_2, TMP14); - vis_pack16(TMP12, DST_2); - - vis_pack16(TMP14, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -MPEG2_MC_EXTERN(vis); - -#endif /* defined(ARCH_SPARC) && defined(ENABLE_VIS) */ diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h deleted file mode 100644 index 253f300a2..000000000 --- a/src/libmpeg2/mpeg2.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * mpeg2.h - * Copyright (C) 1999-2001 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -/* Structure for the mpeg2dec decoder */ - -#ifndef MPEG2_H -#define MPEG2_H - -#include "libmpeg2_accel.h" - -typedef struct mpeg2dec_s { - xine_video_port_t * output; - uint32_t frame_format; - - /* this is where we keep the state of the decoder */ - struct picture_s * picture, *picture_base; - - uint32_t shift; - int new_sequence; - int is_sequence_needed; - int is_wait_for_ip_frames; - int frames_to_drop, drop_frame; - int in_slice; - int seek_mode, is_frame_needed; - - /* the maximum chunk size is determined by vbv_buffer_size */ - /* which is 224K for MP@ML streams. */ - /* (we make no pretenses of decoding anything more than that) */ - /* allocated in init - gcc has problems allocating such big structures */ - uint8_t * chunk_buffer, *chunk_base; - /* pointer to current position in chunk_buffer */ - uint8_t * chunk_ptr; - /* last start code ? */ - uint8_t code; - uint32_t chunk_size; - - int64_t pts; - uint32_t rff_pattern; - int force_aspect; - int force_pan_scan; - - /* AFD data can be found after a sequence, group or picture start code */ - /* and will be stored in afd_value_seen. Later it will be transfered to */ - /* a stream property and stored into afd_value_reported to detect changes */ - int afd_value_seen; - int afd_value_reported; - - xine_stream_t *stream; - - /* a spu decoder for possible closed captions */ - spu_decoder_t *cc_dec; - mpeg2dec_accel_t accel; - -} mpeg2dec_t ; - - -/* initialize mpegdec with a opaque user pointer */ -void mpeg2_init (mpeg2dec_t * mpeg2dec, - xine_video_port_t * output); - -/* destroy everything which was allocated, shutdown the output */ -void mpeg2_close (mpeg2dec_t * mpeg2dec); - -int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, - uint8_t * data_start, uint8_t * data_end, - uint64_t pts); - -void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec, - uint8_t * data_start, uint8_t * data_end); - -void mpeg2_flush (mpeg2dec_t * mpeg2dec); -void mpeg2_reset (mpeg2dec_t * mpeg2dec); -void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec); - -/* Not needed, it is defined as static in decode.c, and no-one else called it - * currently - */ -/* void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); */ - -#endif diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h deleted file mode 100644 index 2e42aace6..000000000 --- a/src/libmpeg2/mpeg2_internal.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * mpeg2_internal.h - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#ifndef MPEG2_INTERNAL_H -#define MPEG2_INTERNAL_H - -#include -#include "accel_xvmc.h" - -#ifdef ENABLE_ALTIVEC -#include -#endif - -/* macroblock modes */ -#define MACROBLOCK_INTRA XINE_MACROBLOCK_INTRA -#define MACROBLOCK_PATTERN XINE_MACROBLOCK_PATTERN -#define MACROBLOCK_MOTION_BACKWARD XINE_MACROBLOCK_MOTION_BACKWARD -#define MACROBLOCK_MOTION_FORWARD XINE_MACROBLOCK_MOTION_FORWARD -#define MACROBLOCK_QUANT XINE_MACROBLOCK_QUANT -#define DCT_TYPE_INTERLACED XINE_MACROBLOCK_DCT_TYPE_INTERLACED - -/* motion_type */ -#define MOTION_TYPE_MASK (3*64) -#define MOTION_TYPE_BASE 64 -#define MC_FIELD (1*64) -#define MC_FRAME (2*64) -#define MC_16X8 (2*64) -#define MC_DMV (3*64) - -/* picture structure */ -#define TOP_FIELD VO_TOP_FIELD -#define BOTTOM_FIELD VO_BOTTOM_FIELD -#define FRAME_PICTURE VO_BOTH_FIELDS - -/* picture coding type (mpeg2 header) */ -#define I_TYPE 1 -#define P_TYPE 2 -#define B_TYPE 3 -#define D_TYPE 4 - -typedef struct motion_s { - uint8_t * ref[2][3]; - uint8_t ** ref2[2]; - int pmv[2][2]; - int f_code[2]; -} motion_t; - -typedef struct picture_s { - /* first, state that carries information from one macroblock to the */ - /* next inside a slice, and is never used outside of mpeg2_slice() */ - - /* DCT coefficients - should be kept aligned ! */ - int16_t DCTblock[64]; - - /* XvMC DCT block and macroblock data for XvMC acceleration */ - xine_macroblocks_t *mc; - int XvMC_mb_type; - int XvMC_mv_field_sel[2][2]; - int XvMC_x; - int XvMC_y; - int XvMC_motion_type; - int XvMC_dmvector[2]; - int XvMC_cbp; - int XvMC_dct_type; - - /* bit parsing stuff */ - uint32_t bitstream_buf; /* current 32 bit working set of buffer */ - int bitstream_bits; /* used bits in working set */ - uint8_t * bitstream_ptr; /* buffer with stream data */ - - uint8_t * dest[3]; - int pitches[3]; - int offset; - unsigned int limit_x; - unsigned int limit_y_16; - unsigned int limit_y_8; - unsigned int limit_y; - - /* Motion vectors */ - /* The f_ and b_ correspond to the forward and backward motion */ - /* predictors */ - motion_t b_motion; - motion_t f_motion; - - /* predictor for DC coefficients in intra blocks */ - int16_t dc_dct_pred[3]; - - int quantizer_scale; /* remove */ - int current_field; /* remove */ - int dmv_offset; /* remove */ - unsigned int v_offset; /* remove */ - - - /* now non-slice-specific information */ - - /* sequence header stuff */ - uint8_t intra_quantizer_matrix [64]; - uint8_t non_intra_quantizer_matrix [64]; - int load_intra_quantizer_matrix; - int load_non_intra_quantizer_matrix; - - /* The width and height of the picture snapped to macroblock units */ - int coded_picture_width; - int coded_picture_height; - - /* The width and height as it appears on header sequence */ - unsigned int display_width, display_height; - - /* picture header stuff */ - - /* what type of picture this is (I, P, B, D) */ - int picture_coding_type; - - int vbv_delay; - int low_delay; - - /* picture coding extension stuff */ - - /* quantization factor for intra dc coefficients */ - int intra_dc_precision; - /* top/bottom/both fields */ - int picture_structure; - /* bool to indicate all predictions are frame based */ - int frame_pred_frame_dct; - /* bool to indicate whether intra blocks have motion vectors */ - /* (for concealment) */ - int concealment_motion_vectors; - /* bit to indicate which quantization table to use */ - int q_scale_type; - /* bool to use different vlc tables */ - int intra_vlc_format; - /* used for DMV MC */ - int top_field_first; - - /* stuff derived from bitstream */ - - /* pointer to the zigzag scan we're supposed to be using */ - uint8_t * scan; - - struct vo_frame_s * current_frame; - struct vo_frame_s * forward_reference_frame; - struct vo_frame_s * backward_reference_frame; - - int frame_width, frame_height; - - int second_field; - - int mpeg1; - - int skip_non_intra_dct; - - /* these things are not needed by the decoder */ - /* this is a temporary interface, we will build a better one later. */ - int aspect_ratio_information; - int saved_aspect_ratio; - int frame_rate_code; - int progressive_sequence; - int repeat_first_field; - int progressive_frame; - uint32_t frame_centre_horizontal_offset; - uint32_t frame_centre_vertical_offset; - uint32_t video_format; - uint32_t colour_description; - uint32_t colour_primatives; - uint32_t transfer_characteristics; - uint32_t matrix_coefficients; - uint32_t display_horizontal_size; - uint32_t display_vertical_size; - uint32_t drop_frame_flag; - uint32_t time_code_hours; - uint32_t time_code_minutes; - uint32_t time_code_seconds; - uint32_t time_code_pictures; - uint32_t closed_gop; - uint32_t broken_link; - - int bitrate; - int frame_rate_ext_n; - int frame_rate_ext_d; - -} picture_t; - -typedef struct cpu_state_s { -#ifdef ARCH_PPC - uint8_t regv[12*16]; -#endif - int dummy; -} cpu_state_t; - -/* cpu_state.c */ -extern void (* mpeg2_cpu_state_save) (cpu_state_t * state); -extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state); -void mpeg2_cpu_state_init (uint32_t mm_accel); - -/* header.c */ -extern uint8_t mpeg2_scan_norm[64]; -extern uint8_t mpeg2_scan_alt[64]; -void mpeg2_header_state_init (picture_t * picture); -int mpeg2_header_picture (picture_t * picture, uint8_t * buffer); -int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer); -int mpeg2_header_extension (picture_t * picture, uint8_t * buffer); -int mpeg2_header_group_of_pictures (picture_t * picture, uint8_t * buffer); - -/* idct.c */ -extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); -extern void (* mpeg2_idct_add) (int16_t * block, uint8_t * dest, int stride); -extern void (* mpeg2_idct) (int16_t * block); -extern void (* mpeg2_zero_block) (int16_t * block); -void mpeg2_idct_init (uint32_t mm_accel); - -/* idct_mlib.c */ -void mpeg2_idct_add_mlib (int16_t * block, uint8_t * dest, int stride); -void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, - int stride); -void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, - int stride); -void mpeg2_idct_mlib (int16_t * block); - -/* idct_mmx.c */ -void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride); -void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int stride); -void mpeg2_idct_mmxext (int16_t * block); -void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride); -void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int stride); -void mpeg2_idct_mmx (int16_t * block); -void mpeg2_zero_block_mmx (int16_t * block); -void mpeg2_idct_mmx_init (void); - -/* idct_altivec.c */ -# ifdef ENABLE_ALTIVEC -void mpeg2_idct_copy_altivec (vector signed short * block, unsigned char * dest, - int stride); -void mpeg2_idct_add_altivec (vector signed short * block, unsigned char * dest, - int stride); -# else /* ! ENABLE_ALTIVEC */ -void mpeg2_idct_copy_altivec (signed short * block, unsigned char * dest, - int stride); -void mpeg2_idct_add_altivec (signed short * block, unsigned char * dest, - int stride); -# endif /* ENABLE_ALTIVEC */ -void mpeg2_idct_altivec_init (void); - -/* motion_comp.c */ -void mpeg2_mc_init (uint32_t mm_accel); - -typedef struct mpeg2_mc_s { - void (* put [8]) (uint8_t * dst, uint8_t *, int32_t, int32_t); - void (* avg [8]) (uint8_t * dst, uint8_t *, int32_t, int32_t); -} mpeg2_mc_t; - -#define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \ - {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \ - MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \ - {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \ - MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \ -}; - -extern mpeg2_mc_t mpeg2_mc; -extern mpeg2_mc_t mpeg2_mc_c; -extern mpeg2_mc_t mpeg2_mc_mmx; -extern mpeg2_mc_t mpeg2_mc_mmxext; -extern mpeg2_mc_t mpeg2_mc_3dnow; -extern mpeg2_mc_t mpeg2_mc_altivec; -extern mpeg2_mc_t mpeg2_mc_mlib; -extern mpeg2_mc_t mpeg2_mc_vis; - -/* slice.c */ -void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer); - -/* stats.c */ -void mpeg2_stats (int code, uint8_t * buffer); - - -#endif diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c deleted file mode 100644 index 8247a9a24..000000000 --- a/src/libmpeg2/slice.c +++ /dev/null @@ -1,1833 +0,0 @@ -/* - * slice.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#include - -#include -#include -#include "mpeg2_internal.h" -#include - -#include "vlc.h" - -static const int non_linear_quantizer_scale [] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 10, 12, 14, 16, 18, 20, 22, - 24, 28, 32, 36, 40, 44, 48, 52, - 56, 64, 72, 80, 88, 96, 104, 112 -}; - -static inline int get_macroblock_modes (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int macroblock_modes; - const MBtab * tab; - - switch (picture->picture_coding_type) { - case I_TYPE: - - tab = MB_I + UBITS (bit_buf, 1); - DUMPBITS (bit_buf, bits, tab->len); - macroblock_modes = tab->modes; - - if ((! (picture->frame_pred_frame_dct)) && - (picture->picture_structure == FRAME_PICTURE)) { - macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; - DUMPBITS (bit_buf, bits, 1); - } - - return macroblock_modes; - - case P_TYPE: - - tab = MB_P + UBITS (bit_buf, 5); - DUMPBITS (bit_buf, bits, tab->len); - macroblock_modes = tab->modes; - - if (picture->picture_structure != FRAME_PICTURE) { - if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - } - return macroblock_modes; - } else if (picture->frame_pred_frame_dct) { - if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) - macroblock_modes |= MC_FRAME; - return macroblock_modes; - } else { - if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - } - if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { - macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; - DUMPBITS (bit_buf, bits, 1); - } - return macroblock_modes; - } - - case B_TYPE: - - tab = MB_B + UBITS (bit_buf, 6); - DUMPBITS (bit_buf, bits, tab->len); - macroblock_modes = tab->modes; - - if (picture->picture_structure != FRAME_PICTURE) { - if (! (macroblock_modes & MACROBLOCK_INTRA)) { - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - } - return macroblock_modes; - } else if (picture->frame_pred_frame_dct) { - /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ - macroblock_modes |= MC_FRAME; - return macroblock_modes; - } else { - if (macroblock_modes & MACROBLOCK_INTRA) - goto intra; - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { - intra: - macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; - DUMPBITS (bit_buf, bits, 1); - } - return macroblock_modes; - } - - case D_TYPE: - - DUMPBITS (bit_buf, bits, 1); - return MACROBLOCK_INTRA; - - default: - return 0; - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_quantizer_scale (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - int quantizer_scale_code; - - quantizer_scale_code = UBITS (bit_buf, 5); - DUMPBITS (bit_buf, bits, 5); - - if (picture->q_scale_type) - return non_linear_quantizer_scale [quantizer_scale_code]; - else - return quantizer_scale_code << 1; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_motion_delta (picture_t * picture, int f_code) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - int delta; - int sign; - const MVtab * tab; - - if (bit_buf & 0x80000000) { - DUMPBITS (bit_buf, bits, 1); - return 0; - } else if (bit_buf >= 0x0c000000) { - - tab = MV_4 + UBITS (bit_buf, 4); - delta = (tab->delta << f_code) + 1; - bits += tab->len + f_code + 1; - bit_buf <<= tab->len; - - sign = SBITS (bit_buf, 1); - bit_buf <<= 1; - - if (f_code) - delta += UBITS (bit_buf, f_code); - bit_buf <<= f_code; - - return (delta ^ sign) - sign; - - } else { - - tab = MV_10 + UBITS (bit_buf, 10); - delta = (tab->delta << f_code) + 1; - bits += tab->len + 1; - bit_buf <<= tab->len; - - sign = SBITS (bit_buf, 1); - bit_buf <<= 1; - - if (f_code) { - NEEDBITS (bit_buf, bits, bit_ptr); - delta += UBITS (bit_buf, f_code); - DUMPBITS (bit_buf, bits, f_code); - } - - return (delta ^ sign) - sign; - - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int bound_motion_vector (int vec, int f_code) -{ -#if 1 - unsigned int limit; - int sign; - - limit = 16 << f_code; - - if ((unsigned int)(vec + limit) < 2 * limit) - return vec; - else { - sign = ((int32_t)vec) >> 31; - return vec - ((2 * limit) ^ sign) + sign; - } -#else - return ((int32_t)vector << (27 - f_code)) >> (27 - f_code); -#endif -} - -static inline int get_dmv (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - const DMVtab * tab; - - tab = DMV_2 + UBITS (bit_buf, 2); - DUMPBITS (bit_buf, bits, tab->len); - return tab->dmv; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_coded_block_pattern (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - const CBPtab * tab; - - NEEDBITS (bit_buf, bits, bit_ptr); - - if (bit_buf >= 0x20000000) { - - tab = CBP_7 + (UBITS (bit_buf, 7) - 16); - DUMPBITS (bit_buf, bits, tab->len); - return tab->cbp; - - } else { - - tab = CBP_9 + UBITS (bit_buf, 9); - DUMPBITS (bit_buf, bits, tab->len); - return tab->cbp; - } - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_luma_dc_dct_diff (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - const DCtab * tab; - int size; - int dc_diff; - - if (bit_buf < 0xf8000000) { - tab = DC_lum_5 + UBITS (bit_buf, 5); - size = tab->size; - if (size) { - bits += tab->len + size; - bit_buf <<= tab->len; - dc_diff = - UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - bit_buf <<= size; - return dc_diff; - } else { - DUMPBITS (bit_buf, bits, 3); - return 0; - } - } else { - tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); - size = tab->size; - DUMPBITS (bit_buf, bits, tab->len); - NEEDBITS (bit_buf, bits, bit_ptr); - dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - DUMPBITS (bit_buf, bits, size); - return dc_diff; - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_chroma_dc_dct_diff (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - const DCtab * tab; - int size; - int dc_diff; - - if (bit_buf < 0xf8000000) { - tab = DC_chrom_5 + UBITS (bit_buf, 5); - size = tab->size; - if (size) { - bits += tab->len + size; - bit_buf <<= tab->len; - dc_diff = - UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - bit_buf <<= size; - return dc_diff; - } else { - DUMPBITS (bit_buf, bits, 2); - return 0; - } - } else { - tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); - size = tab->size; - DUMPBITS (bit_buf, bits, tab->len + 1); - NEEDBITS (bit_buf, bits, bit_ptr); - dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - DUMPBITS (bit_buf, bits, size); - return dc_diff; - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -#define SATURATE(val) \ -do { \ - if ((uint32_t)(val + 2048) > 4095) \ - val = (val > 0) ? 2047 : -2048; \ -} while (0) - -static void get_intra_block_B14 (picture_t * picture) -{ - int i; - int j; - int val; - uint8_t * scan = picture->scan; - uint8_t * quant_matrix = picture->intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - int mismatch; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - dest = picture->DCTblock; - i = 0; - mismatch = ~dest[0]; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - j = scan[i]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - j = scan[i]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = (SBITS (bit_buf, 12) * - quantizer_scale * quant_matrix[j]) / 16; - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - dest[63] ^= mismatch & 1; - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_intra_block_B15 (picture_t * picture) -{ - int i; - int j; - int val; - uint8_t * scan = picture->scan; - uint8_t * quant_matrix = picture->intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - int mismatch; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - dest = picture->DCTblock; - i = 0; - mismatch = ~dest[0]; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - - while (1) { - if (bit_buf >= 0x04000000) { - - tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) { - - normal_code: - j = scan[i]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else { - - /* end of block. I commented out this code because if we */ - /* dont exit here we will still exit at the later test :) */ - - /* if (i >= 128) break; */ /* end of block */ - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check against buffer overflow */ - - j = scan[i]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = (SBITS (bit_buf, 12) * - quantizer_scale * quant_matrix[j]) / 16; - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } - } else if (bit_buf >= 0x02000000) { - tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - dest[63] ^= mismatch & 1; - DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_non_intra_block (picture_t * picture) -{ - int i; - int j; - int val; - uint8_t * scan = picture->scan; - uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - int mismatch; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - i = -1; - mismatch = 1; - dest = picture->DCTblock; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - if (bit_buf >= 0x28000000) { - tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); - goto entry_1; - } else - goto entry_2; - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - entry_1: - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - j = scan[i]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } - - entry_2: - if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - j = scan[i]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; - val = (val * quantizer_scale * quant_matrix[j]) / 32; - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - dest[63] ^= mismatch & 1; - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_mpeg1_intra_block (picture_t * picture) -{ - int i; - int j; - int val; - uint8_t * scan = picture->scan; - uint8_t * quant_matrix = picture->intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - i = 0; - dest = picture->DCTblock; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - j = scan[i]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; - - /* oddification */ - val = (val - 1) | 1; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - j = scan[i]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = SBITS (bit_buf, 8); - if (! (val & 0x7f)) { - DUMPBITS (bit_buf, bits, 8); - val = UBITS (bit_buf, 8) + 2 * val; - } - val = (val * quantizer_scale * quant_matrix[j]) / 16; - - /* oddification */ - val = (val + ~SBITS (val, 1)) | 1; - - SATURATE (val); - dest[j] = val; - - DUMPBITS (bit_buf, bits, 8); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_mpeg1_non_intra_block (picture_t * picture) -{ - int i; - int j; - int val; - uint8_t * scan = picture->scan; - uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - i = -1; - dest = picture->DCTblock; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - if (bit_buf >= 0x28000000) { - tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); - goto entry_1; - } else - goto entry_2; - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - entry_1: - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - j = scan[i]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; - - /* oddification */ - val = (val - 1) | 1; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } - - entry_2: - if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - j = scan[i]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = SBITS (bit_buf, 8); - if (! (val & 0x7f)) { - DUMPBITS (bit_buf, bits, 8); - val = UBITS (bit_buf, 8) + 2 * val; - } - val = 2 * (val + SBITS (val, 1)) + 1; - val = (val * quantizer_scale * quant_matrix[j]) / 32; - - /* oddification */ - val = (val + ~SBITS (val, 1)) | 1; - - SATURATE (val); - dest[j] = val; - - DUMPBITS (bit_buf, bits, 8); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static inline void slice_intra_DCT (picture_t * picture, int cc, - uint8_t * dest, int stride) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - NEEDBITS (bit_buf, bits, bit_ptr); - /* Get the intra DC coefficient and inverse quantize it */ - if (cc == 0) - picture->dc_dct_pred[0] += get_luma_dc_dct_diff (picture); - else - picture->dc_dct_pred[cc] += get_chroma_dc_dct_diff (picture); - picture->DCTblock[0] = - picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision); - - if (picture->mpeg1) { - if (picture->picture_coding_type != D_TYPE) - get_mpeg1_intra_block (picture); - } else if (picture->intra_vlc_format) - get_intra_block_B15 (picture); - else - get_intra_block_B14 (picture); - mpeg2_idct_copy (picture->DCTblock, dest, stride); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline void slice_non_intra_DCT (picture_t * picture, uint8_t * dest, - int stride) -{ - if (picture->mpeg1) - get_mpeg1_non_intra_block (picture); - else - get_non_intra_block (picture); - mpeg2_idct_add (picture->DCTblock, dest, stride); -} - -#define MOTION(table,ref,motion_x,motion_y,size,y) \ - pos_x = 2 * picture->offset + motion_x; \ - pos_y = 2 * picture->v_offset + motion_y + 2 * y; \ - if (pos_x > picture->limit_x) { \ - pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; \ - motion_x = pos_x - 2 * picture->offset; \ - } \ - if (pos_y > picture->limit_y_ ## size){ \ - pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y_ ## size; \ - motion_y = pos_y - 2 * picture->v_offset - 2 * y; \ - } \ - xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ - table[xy_half] (picture->dest[0] + y * picture->pitches[0] + \ - picture->offset, ref[0] + (pos_x >> 1) + \ - (pos_y >> 1) * picture->pitches[0], picture->pitches[0], \ - size); \ - motion_x /= 2; motion_y /= 2; \ - xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ - table[4+xy_half] (picture->dest[1] + y/2 * picture->pitches[1] + \ - (picture->offset >> 1), ref[1] + \ - (((picture->offset + motion_x) >> 1) + \ - ((((picture->v_offset + motion_y) >> 1) + y/2) * \ - picture->pitches[1])), picture->pitches[1], size/2); \ - table[4+xy_half] (picture->dest[2] + y/2 * picture->pitches[2] + \ - (picture->offset >> 1), ref[2] + \ - (((picture->offset + motion_x) >> 1) + \ - ((((picture->v_offset + motion_y) >> 1) + y/2) * \ - picture->pitches[2])), picture->pitches[2], size/2) \ - -#define MOTION_FIELD(table,ref,motion_x,motion_y,dest_field,op,src_field) \ - pos_x = 2 * picture->offset + motion_x; \ - pos_y = picture->v_offset + motion_y; \ - if (pos_x > picture->limit_x) { \ - pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; \ - motion_x = pos_x - 2 * picture->offset; \ - } \ - if (pos_y > picture->limit_y){ \ - pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y; \ - motion_y = pos_y - picture->v_offset; \ - } \ - xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ - table[xy_half] (picture->dest[0] + dest_field * picture->pitches[0] + \ - picture->offset, \ - (ref[0] + (pos_x >> 1) + \ - ((pos_y op) + src_field) * picture->pitches[0]), \ - 2 * picture->pitches[0], 8); \ - motion_x /= 2; motion_y /= 2; \ - xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ - table[4+xy_half] (picture->dest[1] + dest_field * picture->pitches[1] + \ - (picture->offset >> 1), ref[1] + \ - (((picture->offset + motion_x) >> 1) + \ - (((picture->v_offset >> 1) + \ - (motion_y op) + src_field) * picture->pitches[1])), \ - 2 * picture->pitches[1], 4); \ - table[4+xy_half] (picture->dest[2] + dest_field * picture->pitches[2] + \ - (picture->offset >> 1), ref[2] + \ - (((picture->offset + motion_x) >> 1) + \ - (((picture->v_offset >> 1) + \ - (motion_y op) + src_field) * picture->pitches[2])), \ - 2 * picture->pitches[2], 4) - -static void motion_mp1 (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = (motion->pmv[0][0] + - (get_motion_delta (picture, - motion->f_code[0]) << motion->f_code[1])); - motion_x = bound_motion_vector (motion_x, - motion->f_code[0] + motion->f_code[1]); - motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = (motion->pmv[0][1] + - (get_motion_delta (picture, - motion->f_code[0]) << motion->f_code[1])); - motion_y = bound_motion_vector (motion_y, - motion->f_code[0] + motion->f_code[1]); - motion->pmv[0][1] = motion_y; - - MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fr_frame (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = motion->pmv[0][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[0][1] + get_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - - MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fr_field (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y, field; - unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - field = UBITS (bit_buf, 1); - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[0][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture, - motion->f_code[1]); - /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ - motion->pmv[0][1] = motion_y << 1; - - MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); - - NEEDBITS (bit_buf, bits, bit_ptr); - field = UBITS (bit_buf, 1); - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[1][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (picture, - motion->f_code[1]); - /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ - motion->pmv[1][1] = motion_y << 1; - - MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fr_dmv (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; - unsigned int pos_x, pos_y, xy_half, offset; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = motion->pmv[0][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - NEEDBITS (bit_buf, bits, bit_ptr); - dmv_x = get_dmv (picture); - - motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture, - motion->f_code[1]); - /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ - motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; - dmv_y = get_dmv (picture); - - m = picture->top_field_first ? 1 : 3; - other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; - other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; - MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); - - m = picture->top_field_first ? 3 : 1; - other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; - other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; - MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0); - - pos_x = 2 * picture->offset + motion_x; - pos_y = picture->v_offset + motion_y; - if(pos_x > picture->limit_x){ - pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; - motion_x = pos_x - 2 * picture->offset; - } - if(pos_y > picture->limit_y){ - pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y; - motion_y = pos_y - picture->v_offset; - } - xy_half = ((pos_y & 1) << 1) | (pos_x & 1); - offset = (pos_x >> 1) + (pos_y & ~1) * picture->pitches[0]; - mpeg2_mc.avg[xy_half] - (picture->dest[0] + picture->offset, - motion->ref[0][0] + offset, 2 * picture->pitches[0], 8); - mpeg2_mc.avg[xy_half] - (picture->dest[0] + picture->pitches[0] + picture->offset, - motion->ref[0][0] + picture->pitches[0] + offset, - 2 * picture->pitches[0], 8); - motion_x /= 2; motion_y /= 2; - xy_half = ((motion_y & 1) << 1) | (motion_x & 1); - offset = (((picture->offset + motion_x) >> 1) + - (((picture->v_offset >> 1) + (motion_y & ~1)) * - picture->pitches[1])); - mpeg2_mc.avg[4+xy_half] - (picture->dest[1] + (picture->offset >> 1), - motion->ref[0][1] + offset, 2 * picture->pitches[1], 4); - mpeg2_mc.avg[4+xy_half] - (picture->dest[1] + picture->pitches[1] + (picture->offset >> 1), - motion->ref[0][1] + picture->pitches[1] + offset, - 2 * picture->pitches[1], 4); - offset = (((picture->offset + motion_x) >> 1) + - (((picture->v_offset >> 1) + (motion_y & ~1)) * - picture->pitches[2])); - mpeg2_mc.avg[4+xy_half] - (picture->dest[2] + (picture->offset >> 1), - motion->ref[0][2] + offset, 2 * picture->pitches[2], 4); - mpeg2_mc.avg[4+xy_half] - (picture->dest[2] + picture->pitches[2] + (picture->offset >> 1), - motion->ref[0][2] + picture->pitches[2] + offset, - 2 * picture->pitches[2], 4); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_reuse (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ - int motion_x, motion_y; - unsigned int pos_x, pos_y, xy_half; - - motion_x = motion->pmv[0][0]; - motion_y = motion->pmv[0][1]; - - MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); -} - -static void motion_zero (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ - table[0] (picture->dest[0] + picture->offset, - (motion->ref[0][0] + picture->offset + - picture->v_offset * picture->pitches[0]), - picture->pitches[0], 16); - - table[4] (picture->dest[1] + (picture->offset >> 1), - motion->ref[0][1] + (picture->offset >> 1) + - (picture->v_offset >> 1) * picture->pitches[1], - picture->pitches[1], 8); - table[4] (picture->dest[2] + (picture->offset >> 1), - motion->ref[0][2] + (picture->offset >> 1) + - (picture->v_offset >> 1) * picture->pitches[2], - picture->pitches[2], 8); -} - -/* like motion_frame, but parsing without actual motion compensation */ -static void motion_fr_conceal (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - tmp = (picture->f_motion.pmv[0][0] + - get_motion_delta (picture, picture->f_motion.f_code[0])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - tmp = (picture->f_motion.pmv[0][1] + - get_motion_delta (picture, picture->f_motion.f_code[1])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); - picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; - - DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_field (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - uint8_t ** ref_field; - unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - ref_field = motion->ref2[UBITS (bit_buf, 1)]; - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[0][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[0][1] + get_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - - MOTION (table, ref_field, motion_x, motion_y, 16, 0); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_16x8 (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - uint8_t ** ref_field; - unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - ref_field = motion->ref2[UBITS (bit_buf, 1)]; - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[0][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[0][1] + get_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[0][1] = motion_y; - - MOTION (table, ref_field, motion_x, motion_y, 8, 0); - - NEEDBITS (bit_buf, bits, bit_ptr); - ref_field = motion->ref2[UBITS (bit_buf, 1)]; - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[1][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[1][1] + get_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion_y; - - MOTION (table, ref_field, motion_x, motion_y, 8, 8); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_dmv (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y, other_x, other_y; - unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = motion->pmv[0][0] + get_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - NEEDBITS (bit_buf, bits, bit_ptr); - other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (picture); - - motion_y = motion->pmv[0][1] + get_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (picture) + - picture->dmv_offset); - - MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); - MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_conceal (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - DUMPBITS (bit_buf, bits, 1); /* remove field_select */ - - tmp = (picture->f_motion.pmv[0][0] + - get_motion_delta (picture, picture->f_motion.f_code[0])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - tmp = (picture->f_motion.pmv[0][1] + - get_motion_delta (picture, picture->f_motion.f_code[1])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); - picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; - - DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ -#undef bit_buf -#undef bits -#undef bit_ptr -} - -#define MOTION_CALL(routine,direction) \ -do { \ - if ((direction) & MACROBLOCK_MOTION_FORWARD) \ - routine (picture, &(picture->f_motion), mpeg2_mc.put); \ - if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ - routine (picture, &(picture->b_motion), \ - ((direction) & MACROBLOCK_MOTION_FORWARD ? \ - mpeg2_mc.avg : mpeg2_mc.put)); \ -} while (0) - -#define NEXT_MACROBLOCK \ -do { \ - picture->offset += 16; \ - if (picture->offset == picture->coded_picture_width) { \ - do { /* just so we can use the break statement */ \ - if (picture->current_frame->proc_slice) { \ - picture->current_frame->proc_slice (picture->current_frame, \ - picture->dest); \ - } \ - picture->dest[0] += 16 * picture->pitches[0]; \ - picture->dest[1] += 8 * picture->pitches[1]; \ - picture->dest[2] += 8 * picture->pitches[2]; \ - } while (0); \ - picture->v_offset += 16; \ - if (picture->v_offset > picture->limit_y) { \ - if (mpeg2_cpu_state_restore) \ - mpeg2_cpu_state_restore (&cpu_state); \ - return; \ - } \ - picture->offset = 0; \ - } \ -} while (0) - -static inline int slice_init (picture_t * picture, int code) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int offset, height; - struct vo_frame_s * forward_reference_frame; - struct vo_frame_s * backward_reference_frame; - const MBAtab * mba; - - offset = picture->picture_structure == BOTTOM_FIELD; - picture->pitches[0] = picture->current_frame->pitches[0]; - picture->pitches[1] = picture->current_frame->pitches[1]; - picture->pitches[2] = picture->current_frame->pitches[2]; - - if( picture->forward_reference_frame ) { - forward_reference_frame = picture->forward_reference_frame; - } - else { - /* return 1; */ - forward_reference_frame = picture->current_frame; - } - - if( picture->backward_reference_frame ) { - backward_reference_frame = picture->backward_reference_frame; - } - else { - /* return 1; */ - backward_reference_frame = picture->current_frame; - } - - picture->f_motion.ref[0][0] = - forward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); - picture->f_motion.ref[0][1] = - forward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); - picture->f_motion.ref[0][2] = - forward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); - - picture->b_motion.ref[0][0] = - backward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); - picture->b_motion.ref[0][1] = - backward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); - picture->b_motion.ref[0][2] = - backward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); - - if (picture->picture_structure != FRAME_PICTURE) { - uint8_t ** forward_ref; - int bottom_field; - - bottom_field = (picture->picture_structure == BOTTOM_FIELD); - picture->dmv_offset = bottom_field ? 1 : -1; - picture->f_motion.ref2[0] = picture->f_motion.ref[bottom_field]; - picture->f_motion.ref2[1] = picture->f_motion.ref[!bottom_field]; - picture->b_motion.ref2[0] = picture->b_motion.ref[bottom_field]; - picture->b_motion.ref2[1] = picture->b_motion.ref[!bottom_field]; - - forward_ref = forward_reference_frame->base; - if (picture->second_field && (picture->picture_coding_type != B_TYPE)) - forward_ref = picture->current_frame->base; - - picture->f_motion.ref[1][0] = forward_ref[0] + (bottom_field ? 0 : picture->pitches[0]); - picture->f_motion.ref[1][1] = forward_ref[1] + (bottom_field ? 0 : picture->pitches[1]); - picture->f_motion.ref[1][2] = forward_ref[2] + (bottom_field ? 0 : picture->pitches[2]); - - picture->b_motion.ref[1][0] = - backward_reference_frame->base[0] + (bottom_field ? 0 : picture->pitches[0]); - picture->b_motion.ref[1][1] = - backward_reference_frame->base[1] + (bottom_field ? 0 : picture->pitches[1]); - picture->b_motion.ref[1][2] = - backward_reference_frame->base[2] + (bottom_field ? 0 : picture->pitches[2]); - } - - picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; - picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; - - picture->v_offset = (code - 1) * 16; - offset = (code - 1); - if (picture->picture_structure != FRAME_PICTURE) - offset = 2 * offset; - - picture->dest[0] = picture->current_frame->base[0] + picture->pitches[0] * offset * 16; - picture->dest[1] = picture->current_frame->base[1] + picture->pitches[1] * offset * 8; - picture->dest[2] = picture->current_frame->base[2] + picture->pitches[2] * offset * 8; - - height = picture->coded_picture_height; - switch (picture->picture_structure) { - case BOTTOM_FIELD: - picture->dest[0] += picture->pitches[0]; - picture->dest[1] += picture->pitches[1]; - picture->dest[2] += picture->pitches[2]; - /* follow thru */ - case TOP_FIELD: - picture->pitches[0] <<= 1; - picture->pitches[1] <<= 1; - picture->pitches[2] <<= 1; - height >>= 1; - } - picture->limit_x = 2 * picture->coded_picture_width - 32; - picture->limit_y_16 = 2 * height - 32; - picture->limit_y_8 = 2 * height - 16; - picture->limit_y = height - 16; - - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); - - picture->quantizer_scale = get_quantizer_scale (picture); - - /* ignore intra_slice and all the extra data */ - while (bit_buf & 0x80000000) { - DUMPBITS (bit_buf, bits, 9); - NEEDBITS (bit_buf, bits, bit_ptr); - } - - /* decode initial macroblock address increment */ - offset = 0; - while (1) { - if (bit_buf >= 0x08000000) { - mba = MBA_5 + (UBITS (bit_buf, 6) - 2); - break; - } else if (bit_buf >= 0x01800000) { - mba = MBA_11 + (UBITS (bit_buf, 12) - 24); - break; - } else switch (UBITS (bit_buf, 12)) { - case 8: /* macroblock_escape */ - offset += 33; - DUMPBITS (bit_buf, bits, 11); - NEEDBITS (bit_buf, bits, bit_ptr); - continue; - case 15: /* macroblock_stuffing (MPEG1 only) */ - bit_buf &= 0xfffff; - DUMPBITS (bit_buf, bits, 11); - NEEDBITS (bit_buf, bits, bit_ptr); - continue; - default: /* error */ - return 1; - } - } - DUMPBITS (bit_buf, bits, mba->len + 1); - picture->offset = (offset + mba->mba) << 4; - - while (picture->offset - picture->coded_picture_width >= 0) { - picture->offset -= picture->coded_picture_width; - if ((picture->current_frame->proc_slice == NULL) || - (picture->picture_coding_type != B_TYPE)) { - picture->dest[0] += 16 * picture->pitches[0]; - picture->dest[1] += 8 * picture->pitches[1]; - picture->dest[2] += 8 * picture->pitches[2]; - } - picture->v_offset += 16; - } - if (picture->v_offset > picture->limit_y) - return 1; - - return 0; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - cpu_state_t cpu_state; - - bitstream_init (picture, buffer); - - if (slice_init (picture, code)) - return; - - if (mpeg2_cpu_state_save) - mpeg2_cpu_state_save (&cpu_state); - - while (1) { - int macroblock_modes; - int mba_inc; - const MBAtab * mba; - - NEEDBITS (bit_buf, bits, bit_ptr); - - macroblock_modes = get_macroblock_modes (picture); - - /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */ - if (macroblock_modes & MACROBLOCK_QUANT) - picture->quantizer_scale = get_quantizer_scale (picture); - - if (macroblock_modes & MACROBLOCK_INTRA) { - - int DCT_offset, DCT_stride; - int offset; - uint8_t * dest_y; - - if (picture->concealment_motion_vectors) { - if (picture->picture_structure == FRAME_PICTURE) - motion_fr_conceal (picture); - else - motion_fi_conceal (picture); - } else { - picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; - picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; - } - - if (macroblock_modes & DCT_TYPE_INTERLACED) { - DCT_offset = picture->pitches[0]; - DCT_stride = picture->pitches[0] * 2; - } else { - DCT_offset = picture->pitches[0] * 8; - DCT_stride = picture->pitches[0]; - } - - offset = picture->offset; - dest_y = picture->dest[0] + offset; - slice_intra_DCT (picture, 0, dest_y, DCT_stride); - slice_intra_DCT (picture, 0, dest_y + 8, DCT_stride); - slice_intra_DCT (picture, 0, dest_y + DCT_offset, DCT_stride); - slice_intra_DCT (picture, 0, dest_y + DCT_offset + 8, DCT_stride); - slice_intra_DCT (picture, 1, picture->dest[1] + (offset >> 1), - picture->pitches[1]); - slice_intra_DCT (picture, 2, picture->dest[2] + (offset >> 1), - picture->pitches[2]); - - if (picture->picture_coding_type == D_TYPE) { - NEEDBITS (bit_buf, bits, bit_ptr); - DUMPBITS (bit_buf, bits, 1); - } - } else { - - if (picture->picture_structure == FRAME_PICTURE) - switch (macroblock_modes & MOTION_TYPE_MASK) { - case MC_FRAME: - if (picture->mpeg1) - MOTION_CALL (motion_mp1, macroblock_modes); - else - MOTION_CALL (motion_fr_frame, macroblock_modes); - break; - - case MC_FIELD: - MOTION_CALL (motion_fr_field, macroblock_modes); - break; - - case MC_DMV: - MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); - break; - - case 0: - /* non-intra mb without forward mv in a P picture */ - picture->f_motion.pmv[0][0] = 0; - picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = 0; - picture->f_motion.pmv[1][1] = 0; - MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); - break; - } - else - switch (macroblock_modes & MOTION_TYPE_MASK) { - case MC_FIELD: - MOTION_CALL (motion_fi_field, macroblock_modes); - break; - - case MC_16X8: - MOTION_CALL (motion_fi_16x8, macroblock_modes); - break; - - case MC_DMV: - MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); - break; - - case 0: - /* non-intra mb without forward mv in a P picture */ - picture->f_motion.pmv[0][0] = 0; - picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = 0; - picture->f_motion.pmv[1][1] = 0; - MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); - break; - } - - if (macroblock_modes & MACROBLOCK_PATTERN) { - int coded_block_pattern; - int DCT_offset, DCT_stride; - int offset; - uint8_t * dest_y; - - if (macroblock_modes & DCT_TYPE_INTERLACED) { - DCT_offset = picture->pitches[0]; - DCT_stride = picture->pitches[0] * 2; - } else { - DCT_offset = picture->pitches[0] * 8; - DCT_stride = picture->pitches[0]; - } - - coded_block_pattern = get_coded_block_pattern (picture); - - offset = picture->offset; - dest_y = picture->dest[0] + offset; - if (coded_block_pattern & 0x20) - slice_non_intra_DCT (picture, dest_y, DCT_stride); - if (coded_block_pattern & 0x10) - slice_non_intra_DCT (picture, dest_y + 8, DCT_stride); - if (coded_block_pattern & 0x08) - slice_non_intra_DCT (picture, dest_y + DCT_offset, - DCT_stride); - if (coded_block_pattern & 0x04) - slice_non_intra_DCT (picture, dest_y + DCT_offset + 8, - DCT_stride); - if (coded_block_pattern & 0x2) - slice_non_intra_DCT (picture, - picture->dest[1] + (offset >> 1), - picture->pitches[1]); - if (coded_block_pattern & 0x1) - slice_non_intra_DCT (picture, - picture->dest[2] + (offset >> 1), - picture->pitches[2]); - } - - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; - } - - NEXT_MACROBLOCK; - - NEEDBITS (bit_buf, bits, bit_ptr); - mba_inc = 0; - while (1) { - if (bit_buf >= 0x10000000) { - mba = MBA_5 + (UBITS (bit_buf, 5) - 2); - break; - } else if (bit_buf >= 0x03000000) { - mba = MBA_11 + (UBITS (bit_buf, 11) - 24); - break; - } else switch (UBITS (bit_buf, 11)) { - case 8: /* macroblock_escape */ - mba_inc += 33; - /* pass through */ - case 15: /* macroblock_stuffing (MPEG1 only) */ - DUMPBITS (bit_buf, bits, 11); - NEEDBITS (bit_buf, bits, bit_ptr); - continue; - default: /* end of slice, or error */ - if (mpeg2_cpu_state_restore) - mpeg2_cpu_state_restore (&cpu_state); - return; - } - } - DUMPBITS (bit_buf, bits, mba->len); - mba_inc += mba->mba; - - if (mba_inc) { - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; - - if (picture->picture_coding_type == P_TYPE) { - picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - - do { - MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); - NEXT_MACROBLOCK; - } while (--mba_inc); - } else { - do { - MOTION_CALL (motion_reuse, macroblock_modes); - NEXT_MACROBLOCK; - } while (--mba_inc); - } - } - } -#undef bit_buf -#undef bits -#undef bit_ptr -} diff --git a/src/libmpeg2/slice_xvmc.c b/src/libmpeg2/slice_xvmc.c deleted file mode 100644 index 014ae7924..000000000 --- a/src/libmpeg2/slice_xvmc.c +++ /dev/null @@ -1,1988 +0,0 @@ -/* - * slice_xvmc.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#include -#include /* memcpy/memset, try to remove */ -#include -#include - -#include -#include -#include "mpeg2_internal.h" -#include - -#include -#include "accel_xvmc.h" -#include "xvmc.h" - - -#define MOTION_ACCEL XINE_VO_MOTION_ACCEL -#define IDCT_ACCEL XINE_VO_IDCT_ACCEL -#define SIGNED_INTRA XINE_VO_SIGNED_INTRA -#define ACCEL (MOTION_ACCEL | IDCT_ACCEL) - -#include "vlc.h" -/* original (non-patched) scan tables */ - -static const uint8_t mpeg2_scan_norm_orig[64] ATTR_ALIGN(16) = -{ - /* Zig-Zag scan pattern */ - 0, 1, 8,16, 9, 2, 3,10, - 17,24,32,25,18,11, 4, 5, - 12,19,26,33,40,48,41,34, - 27,20,13, 6, 7,14,21,28, - 35,42,49,56,57,50,43,36, - 29,22,15,23,30,37,44,51, - 58,59,52,45,38,31,39,46, - 53,60,61,54,47,55,62,63 -}; - -static const uint8_t mpeg2_scan_alt_orig[64] ATTR_ALIGN(16) = -{ - /* Alternate scan pattern */ - 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, - 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, - 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, - 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 -}; - -static uint8_t mpeg2_scan_alt_ptable[64] ATTR_ALIGN(16); -static uint8_t mpeg2_scan_norm_ptable[64] ATTR_ALIGN(16); -static uint8_t mpeg2_scan_orig_ptable[64] ATTR_ALIGN(16); - -void xvmc_setup_scan_ptable( void ) -{ - int i; - for (i=0; i<64; ++i) { - mpeg2_scan_norm_ptable[mpeg2_scan_norm_orig[i]] = mpeg2_scan_norm[i]; - mpeg2_scan_alt_ptable[mpeg2_scan_alt_orig[i]] = mpeg2_scan_alt[i]; - mpeg2_scan_orig_ptable[i] = i; - } -} - - -static const int non_linear_quantizer_scale [] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 10, 12, 14, 16, 18, 20, 22, - 24, 28, 32, 36, 40, 44, 48, 52, - 56, 64, 72, 80, 88, 96, 104, 112 -}; - -static inline int get_xvmc_macroblock_modes (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int macroblock_modes; - const MBtab * tab; - - switch (picture->picture_coding_type) { - case I_TYPE: - - tab = MB_I + UBITS (bit_buf, 1); - DUMPBITS (bit_buf, bits, tab->len); - macroblock_modes = tab->modes; - - if ((! (picture->frame_pred_frame_dct)) && - (picture->picture_structure == FRAME_PICTURE)) { - macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; - DUMPBITS (bit_buf, bits, 1); - } - - return macroblock_modes; - - case P_TYPE: - - tab = MB_P + UBITS (bit_buf, 5); - DUMPBITS (bit_buf, bits, tab->len); - macroblock_modes = tab->modes; - - if (picture->picture_structure != FRAME_PICTURE) { - if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - } - return macroblock_modes; - } else if (picture->frame_pred_frame_dct) { - if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) - macroblock_modes |= MC_FRAME; - return macroblock_modes; - } else { - if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - } - if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { - macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; - DUMPBITS (bit_buf, bits, 1); - } - return macroblock_modes; - } - - case B_TYPE: - - tab = MB_B + UBITS (bit_buf, 6); - DUMPBITS (bit_buf, bits, tab->len); - macroblock_modes = tab->modes; - - if (picture->picture_structure != FRAME_PICTURE) { - if (! (macroblock_modes & MACROBLOCK_INTRA)) { - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - } - return macroblock_modes; - } else if (picture->frame_pred_frame_dct) { - /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ - macroblock_modes |= MC_FRAME; - return macroblock_modes; - } else { - if (macroblock_modes & MACROBLOCK_INTRA) - goto intra; - macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; - DUMPBITS (bit_buf, bits, 2); - if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { - intra: - macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; - DUMPBITS (bit_buf, bits, 1); - } - return macroblock_modes; - } - - case D_TYPE: - - DUMPBITS (bit_buf, bits, 1); - return MACROBLOCK_INTRA; - - default: - return 0; - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_xvmc_quantizer_scale (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - int quantizer_scale_code; - - quantizer_scale_code = UBITS (bit_buf, 5); - DUMPBITS (bit_buf, bits, 5); - - if (picture->q_scale_type) - return non_linear_quantizer_scale [quantizer_scale_code]; - else - return quantizer_scale_code << 1; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_xvmc_motion_delta (picture_t * picture, int f_code) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - int delta; - int sign; - const MVtab * tab; - - if (bit_buf & 0x80000000) { - DUMPBITS (bit_buf, bits, 1); - return 0; - } else if (bit_buf >= 0x0c000000) { - - tab = MV_4 + UBITS (bit_buf, 4); - delta = (tab->delta << f_code) + 1; - bits += tab->len + f_code + 1; - bit_buf <<= tab->len; - - sign = SBITS (bit_buf, 1); - bit_buf <<= 1; - - if (f_code) - delta += UBITS (bit_buf, f_code); - bit_buf <<= f_code; - - return (delta ^ sign) - sign; - - } else { - - tab = MV_10 + UBITS (bit_buf, 10); - delta = (tab->delta << f_code) + 1; - bits += tab->len + 1; - bit_buf <<= tab->len; - - sign = SBITS (bit_buf, 1); - bit_buf <<= 1; - - if (f_code) { - NEEDBITS (bit_buf, bits, bit_ptr); - delta += UBITS (bit_buf, f_code); - DUMPBITS (bit_buf, bits, f_code); - } - - return (delta ^ sign) - sign; - - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int bound_motion_vector (int vec, int f_code) -{ -#if 1 - unsigned int limit; - int sign; - - limit = 16 << f_code; - - if ((unsigned int)(vec + limit) < 2 * limit) - return vec; - else { - sign = ((int32_t)vec) >> 31; - return vec - ((2 * limit) ^ sign) + sign; - } -#else - return ((int32_t)vec << (27 - f_code)) >> (27 - f_code); -#endif -} - -static inline int get_xvmc_dmv (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - const DMVtab * tab; - - tab = DMV_2 + UBITS (bit_buf, 2); - DUMPBITS (bit_buf, bits, tab->len); - return tab->dmv; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_xvmc_coded_block_pattern (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - - const CBPtab * tab; - - NEEDBITS (bit_buf, bits, bit_ptr); - - if (bit_buf >= 0x20000000) { - - tab = CBP_7 + (UBITS (bit_buf, 7) - 16); - DUMPBITS (bit_buf, bits, tab->len); - return tab->cbp; - - } else { - - tab = CBP_9 + UBITS (bit_buf, 9); - DUMPBITS (bit_buf, bits, tab->len); - return tab->cbp; - } - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_xvmc_luma_dc_dct_diff (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - const DCtab * tab; - int size; - int dc_diff; - - if (bit_buf < 0xf8000000) { - tab = DC_lum_5 + UBITS (bit_buf, 5); - size = tab->size; - if (size) { - bits += tab->len + size; - bit_buf <<= tab->len; - dc_diff = - UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - bit_buf <<= size; - return dc_diff; - } else { - DUMPBITS (bit_buf, bits, 3); - return 0; - } - } else { - tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); - size = tab->size; - DUMPBITS (bit_buf, bits, tab->len); - NEEDBITS (bit_buf, bits, bit_ptr); - dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - DUMPBITS (bit_buf, bits, size); - return dc_diff; - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline int get_xvmc_chroma_dc_dct_diff (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - const DCtab * tab; - int size; - int dc_diff; - - if (bit_buf < 0xf8000000) { - tab = DC_chrom_5 + UBITS (bit_buf, 5); - size = tab->size; - if (size) { - bits += tab->len + size; - bit_buf <<= tab->len; - dc_diff = - UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - bit_buf <<= size; - return dc_diff; - } else { - DUMPBITS (bit_buf, bits, 2); - return 0; - } - } else { - tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); - size = tab->size; - DUMPBITS (bit_buf, bits, tab->len + 1); - NEEDBITS (bit_buf, bits, bit_ptr); - dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); - DUMPBITS (bit_buf, bits, size); - return dc_diff; - } -#undef bit_buf -#undef bits -#undef bit_ptr -} - -#define SATURATE(val) \ -do { \ - if ((uint32_t)(val + 2048) > 4095) \ - val = (val > 0) ? 2047 : -2048; \ -} while (0) - -static void get_xvmc_intra_block_B14 (picture_t * picture) -{ - int i; - int j; - int l; - int val; - const uint8_t * scan = picture->scan; - uint8_t * scan_ptable = mpeg2_scan_orig_ptable; - uint8_t * quant_matrix = picture->intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - int mismatch; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - dest = picture->mc->blockptr; - - if( picture->mc->xvmc_accel & IDCT_ACCEL ) { - if ( scan == mpeg2_scan_norm ) { - scan = mpeg2_scan_norm_orig; - scan_ptable = mpeg2_scan_norm_ptable; - } else { - scan = mpeg2_scan_alt_orig; - scan_ptable = mpeg2_scan_alt_ptable; - } - } - - i = 0; - mismatch = ~dest[0]; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - l = scan_ptable[j = scan[i]]; - - bit_buf <<= tab->len; - bits += tab->len + 1; - val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - l = scan_ptable[j = scan[i]]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = (SBITS (bit_buf, 12) * - quantizer_scale * quant_matrix[l]) / 16; - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - - dest[63] ^= mismatch & 1; - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_xvmc_intra_block_B15 (picture_t * picture) -{ - int i; - int j; - int l; - int val; - const uint8_t * scan = picture->scan; - uint8_t * scan_ptable = mpeg2_scan_orig_ptable; - uint8_t * quant_matrix = picture->intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - int mismatch; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - dest = picture->mc->blockptr; - - if( picture->mc->xvmc_accel & IDCT_ACCEL ) { - if ( scan == mpeg2_scan_norm ) { - scan = mpeg2_scan_norm_orig; - scan_ptable = mpeg2_scan_norm_ptable; - } else { - scan = mpeg2_scan_alt_orig; - scan_ptable = mpeg2_scan_alt_ptable; - } - } - - i = 0; - mismatch = ~dest[0]; - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - - while (1) { - if (bit_buf >= 0x04000000) { - - tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) { - - normal_code: - l = scan_ptable[j = scan[i]]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else { - - /* end of block. I commented out this code because if we */ - /* dont exit here we will still exit at the later test :) */ - - /* if (i >= 128) break; */ /* end of block */ - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check against buffer overflow */ - - l = scan_ptable[j = scan[i]]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = (SBITS (bit_buf, 12) * - quantizer_scale * quant_matrix[l]) / 16; - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } - } else if (bit_buf >= 0x02000000) { - tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - - dest[63] ^= mismatch & 1; - DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_xvmc_non_intra_block (picture_t * picture) -{ - int i; - int j; - int l; - int val; - const uint8_t * scan = picture->scan; - uint8_t * scan_ptable = mpeg2_scan_orig_ptable; - uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - int mismatch; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - i = -1; - mismatch = 1; - - dest = picture->mc->blockptr; - - if( picture->mc->xvmc_accel & IDCT_ACCEL ) { - if ( scan == mpeg2_scan_norm ) { - scan = mpeg2_scan_norm_orig; - scan_ptable = mpeg2_scan_norm_ptable; - } else { - scan = mpeg2_scan_alt_orig; - scan_ptable = mpeg2_scan_alt_ptable; - } - } - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - if (bit_buf >= 0x28000000) { - tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); - goto entry_1; - } else - goto entry_2; - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - entry_1: - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - l = scan_ptable[j = scan[i]]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = ((2*tab->level+1) * quantizer_scale * quant_matrix[l]) >> 5; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } - - entry_2: - if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - l = scan_ptable[j = scan[i]]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; - val = (val * quantizer_scale * quant_matrix[l]) / 32; - - SATURATE (val); - dest[j] = val; - mismatch ^= val; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - dest[63] ^= mismatch & 1; - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_xvmc_mpeg1_intra_block (picture_t * picture) -{ - int i; - int j; - int l; - int val; - const uint8_t * scan = picture->scan; - uint8_t * scan_ptable = mpeg2_scan_orig_ptable; - uint8_t * quant_matrix = picture->intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - i = 0; - - dest = picture->mc->blockptr; - - if( picture->mc->xvmc_accel & IDCT_ACCEL ) { - if ( scan == mpeg2_scan_norm ) { - scan = mpeg2_scan_norm_orig; - scan_ptable = mpeg2_scan_norm_ptable; - } else { - scan = mpeg2_scan_alt_orig; - scan_ptable = mpeg2_scan_alt_ptable; - } - } - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - l = scan_ptable[j = scan[i]]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; - - /* oddification */ - val = (val - 1) | 1; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - l = scan_ptable[j = scan[i]]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = SBITS (bit_buf, 8); - if (! (val & 0x7f)) { - DUMPBITS (bit_buf, bits, 8); - val = UBITS (bit_buf, 8) + 2 * val; - } - val = (val * quantizer_scale * quant_matrix[l]) / 16; - - /* oddification */ - val = (val + ~SBITS (val, 1)) | 1; - - SATURATE (val); - dest[j] = val; - - DUMPBITS (bit_buf, bits, 8); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static void get_xvmc_mpeg1_non_intra_block (picture_t * picture) -{ - int i; - int j; - int l; - int val; - const uint8_t * scan = picture->scan; - uint8_t * scan_ptable = mpeg2_scan_orig_ptable; - uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; - int quantizer_scale = picture->quantizer_scale; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - uint8_t * bit_ptr; - int16_t * dest; - - i = -1; - - dest = picture->mc->blockptr; - - if( picture->mc->xvmc_accel & IDCT_ACCEL ) { - if ( scan == mpeg2_scan_norm ) { - scan = mpeg2_scan_norm_orig; - scan_ptable = mpeg2_scan_norm_ptable; - } else { - scan = mpeg2_scan_alt_orig; - scan_ptable = mpeg2_scan_alt_ptable; - } - } - - bit_buf = picture->bitstream_buf; - bits = picture->bitstream_bits; - bit_ptr = picture->bitstream_ptr; - - NEEDBITS (bit_buf, bits, bit_ptr); - if (bit_buf >= 0x28000000) { - tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); - goto entry_1; - } else - goto entry_2; - - while (1) { - if (bit_buf >= 0x28000000) { - - tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); - - entry_1: - i += tab->run; - if (i >= 64) - break; /* end of block */ - - normal_code: - l = scan_ptable[j = scan[i]]; - bit_buf <<= tab->len; - bits += tab->len + 1; - val = ((2*tab->level+1) * quantizer_scale * quant_matrix[l]) >> 5; - - /* oddification */ - val = (val - 1) | 1; - - /* if (bitstream_get (1)) val = -val; */ - val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); - - SATURATE (val); - dest[j] = val; - - bit_buf <<= 1; - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } - - entry_2: - if (bit_buf >= 0x04000000) { - - tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); - - i += tab->run; - if (i < 64) - goto normal_code; - - /* escape code */ - - i += UBITS (bit_buf << 6, 6) - 64; - if (i >= 64) - break; /* illegal, check needed to avoid buffer overflow */ - - l = scan_ptable[j = scan[i]]; - - DUMPBITS (bit_buf, bits, 12); - NEEDBITS (bit_buf, bits, bit_ptr); - val = SBITS (bit_buf, 8); - if (! (val & 0x7f)) { - DUMPBITS (bit_buf, bits, 8); - val = UBITS (bit_buf, 8) + 2 * val; - } - val = 2 * (val + SBITS (val, 1)) + 1; - val = (val * quantizer_scale * quant_matrix[l]) / 32; - - /* oddification */ - val = (val + ~SBITS (val, 1)) | 1; - - SATURATE (val); - dest[j] = val; - - DUMPBITS (bit_buf, bits, 8); - NEEDBITS (bit_buf, bits, bit_ptr); - - continue; - - } else if (bit_buf >= 0x02000000) { - tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00800000) { - tab = DCT_13 + (UBITS (bit_buf, 13) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else if (bit_buf >= 0x00200000) { - tab = DCT_15 + (UBITS (bit_buf, 15) - 16); - i += tab->run; - if (i < 64) - goto normal_code; - } else { - tab = DCT_16 + UBITS (bit_buf, 16); - bit_buf <<= 16; - GETWORD (bit_buf, bits + 16, bit_ptr); - i += tab->run; - if (i < 64) - goto normal_code; - } - break; /* illegal, check needed to avoid buffer overflow */ - } - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ - picture->bitstream_buf = bit_buf; - picture->bitstream_bits = bits; - picture->bitstream_ptr = bit_ptr; -} - -static inline void slice_xvmc_intra_DCT (picture_t * picture, int cc, - uint8_t * dest, int stride) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - NEEDBITS (bit_buf, bits, bit_ptr); - /* Get the intra DC coefficient and inverse quantize it */ - - // printf("slice: slice_xvmc_intra_DCT cc=%d pred[0]=%d\n",cc,picture->dc_dct_pred[0]); - if (cc == 0) - picture->dc_dct_pred[0] += get_xvmc_luma_dc_dct_diff (picture); - else - picture->dc_dct_pred[cc] += get_xvmc_chroma_dc_dct_diff (picture); - //TODO conversion to signed format - // printf("slice: pred[0]=%d presision=%d\n",picture->dc_dct_pred[0], - // picture->intra_dc_precision); - - mpeg2_zero_block(picture->mc->blockptr); - - picture->mc->blockptr[0] = picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision); - - if (picture->mpeg1) { - if (picture->picture_coding_type != D_TYPE) - get_xvmc_mpeg1_intra_block (picture); - } else if (picture->intra_vlc_format) - get_xvmc_intra_block_B15 (picture); - else - get_xvmc_intra_block_B14 (picture); - - if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL) { - //motion_comp only no idct acceleration so do it in software - mpeg2_idct (picture->mc->blockptr); - } - picture->mc->blockptr += 64; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static inline void slice_xvmc_non_intra_DCT (picture_t * picture, uint8_t * dest, - int stride) -{ - mpeg2_zero_block(picture->mc->blockptr); - - if (picture->mpeg1) - get_xvmc_mpeg1_non_intra_block (picture); - else - get_xvmc_non_intra_block (picture); - - if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL) { - // motion comp only no idct acceleration so do it in sw - mpeg2_idct (picture->mc->blockptr); - } - picture->mc->blockptr += 64; -} - -static void motion_mp1 (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = (motion->pmv[0][0] + - (get_xvmc_motion_delta (picture, - motion->f_code[0]) << motion->f_code[1])); - motion_x = bound_motion_vector (motion_x, - motion->f_code[0] + motion->f_code[1]); - motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = (motion->pmv[0][1] + - (get_xvmc_motion_delta (picture, - motion->f_code[0]) << motion->f_code[1])); - motion_y = bound_motion_vector (motion_y, - motion->f_code[0] + motion->f_code[1]); - motion->pmv[0][1] = motion_y; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fr_frame (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fr_field (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int), - int dir) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y, field; - // unsigned int pos_x, pos_y, xy_half; - - NEEDBITS (bit_buf, bits, bit_ptr); - field = UBITS (bit_buf, 1); - picture->XvMC_mv_field_sel[0][dir] = field; - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = (motion->pmv[0][1] >> 1) + get_xvmc_motion_delta (picture, - motion->f_code[1]); - /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ - motion->pmv[0][1] = motion_y << 1; - - NEEDBITS (bit_buf, bits, bit_ptr); - field = UBITS (bit_buf, 1); - //TODO look at field select need bob (weave ok) - picture->XvMC_mv_field_sel[1][dir] = field; - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[1][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = (motion->pmv[1][1] >> 1) + get_xvmc_motion_delta (picture, - motion->f_code[1]); - /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ - motion->pmv[1][1] = motion_y << 1; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fr_dmv (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - - // TODO field select ?? possible need to be 0 - picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - NEEDBITS (bit_buf, bits, bit_ptr); - - motion_y = (motion->pmv[0][1] >> 1) + get_xvmc_motion_delta (picture, - motion->f_code[1]); - /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ - motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_reuse (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ - int motion_x, motion_y; - - motion_x = motion->pmv[0][0]; - motion_y = motion->pmv[0][1]; - -} - -/* like motion_frame, but parsing without actual motion compensation */ -static void motion_fr_conceal (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - tmp = (picture->f_motion.pmv[0][0] + - get_xvmc_motion_delta (picture, picture->f_motion.f_code[0])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - tmp = (picture->f_motion.pmv[0][1] + - get_xvmc_motion_delta (picture, picture->f_motion.f_code[1])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); - picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; - - DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_field (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - uint8_t ** ref_field; - - NEEDBITS (bit_buf, bits, bit_ptr); - ref_field = motion->ref2[UBITS (bit_buf, 1)]; - - // TODO field select may need to do something here for bob (weave ok) - picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; - - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_16x8 (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - uint8_t ** ref_field; - - NEEDBITS (bit_buf, bits, bit_ptr); - ref_field = motion->ref2[UBITS (bit_buf, 1)]; - - // TODO field select may need to do something here bob (weave ok) - picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; - - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[0][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[0][1] = motion_y; - - - NEEDBITS (bit_buf, bits, bit_ptr); - ref_field = motion->ref2[UBITS (bit_buf, 1)]; - - // TODO field select may need to do something here for bob (weave ok) - picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; - - DUMPBITS (bit_buf, bits, 1); - - motion_x = motion->pmv[1][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion_x; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_y = motion->pmv[1][1] + get_xvmc_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion_y; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - -static void motion_fi_dmv (picture_t * picture, motion_t * motion, - void (** table) (uint8_t *, uint8_t *, int, int)) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int motion_x, motion_y; - - NEEDBITS (bit_buf, bits, bit_ptr); - motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, - motion->f_code[0]); - motion_x = bound_motion_vector (motion_x, motion->f_code[0]); - motion->pmv[1][0] = motion->pmv[0][0] = motion_x; - NEEDBITS (bit_buf, bits, bit_ptr); - - motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, - motion->f_code[1]); - motion_y = bound_motion_vector (motion_y, motion->f_code[1]); - motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - - // TODO field select may need to do something here for bob (weave ok) - picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; - -#undef bit_buf -#undef bits -#undef bit_ptr -} - - -static void motion_fi_conceal (picture_t * picture) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - DUMPBITS (bit_buf, bits, 1); /* remove field_select */ - - tmp = (picture->f_motion.pmv[0][0] + - get_xvmc_motion_delta (picture, picture->f_motion.f_code[0])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; - - NEEDBITS (bit_buf, bits, bit_ptr); - tmp = (picture->f_motion.pmv[0][1] + - get_xvmc_motion_delta (picture, picture->f_motion.f_code[1])); - tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); - picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; - - DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ -#undef bit_buf -#undef bits -#undef bit_ptr -} - -#define MOTION_CALL(routine,direction) \ -do { \ - if ((direction) & MACROBLOCK_MOTION_FORWARD) \ - routine (picture, &(picture->f_motion), mpeg2_mc.put); \ - if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ - routine (picture, &(picture->b_motion), \ - ((direction) & MACROBLOCK_MOTION_FORWARD ? \ - mpeg2_mc.avg : mpeg2_mc.put)); \ -} while (0) - -#define NEXT_MACROBLOCK \ -do { \ - picture->offset += 16; \ - if (picture->offset == picture->coded_picture_width) { \ - do { /* just so we can use the break statement */ \ - if (picture->current_frame->proc_slice) { \ - picture->current_frame->proc_slice (picture->current_frame, \ - picture->dest); \ - if (picture->picture_coding_type == B_TYPE) \ - break; \ - } \ - picture->dest[0] += 16 * picture->pitches[0]; \ - picture->dest[1] += 8 * picture->pitches[1]; \ - picture->dest[2] += 8 * picture->pitches[2]; \ - } while (0); \ - picture->v_offset += 16; \ - if (picture->v_offset > picture->limit_y) { \ - if (mpeg2_cpu_state_restore) \ - mpeg2_cpu_state_restore (&cpu_state); \ - return; \ - } \ - picture->offset = 0; \ - } \ -} while (0) - -static inline int slice_xvmc_init (picture_t * picture, int code) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - int offset, height; - struct vo_frame_s * forward_reference_frame; - struct vo_frame_s * backward_reference_frame; - const MBAtab * mba; - - offset = picture->picture_structure == BOTTOM_FIELD; - picture->pitches[0] = picture->current_frame->pitches[0]; - picture->pitches[1] = picture->current_frame->pitches[1]; - picture->pitches[2] = picture->current_frame->pitches[2]; - - if( picture->forward_reference_frame ) { - forward_reference_frame = picture->forward_reference_frame; - } - else { - /* return 1; */ - forward_reference_frame = picture->current_frame; - } - - if( picture->backward_reference_frame ) { - backward_reference_frame = picture->backward_reference_frame; - } - else { - /* return 1; */ - backward_reference_frame = picture->current_frame; - } - - picture->f_motion.ref[0][0] = - forward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); - picture->f_motion.ref[0][1] = - forward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); - picture->f_motion.ref[0][2] = - forward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); - - picture->b_motion.ref[0][0] = - backward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); - picture->b_motion.ref[0][1] = - backward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); - picture->b_motion.ref[0][2] = - backward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); - - if (picture->picture_structure != FRAME_PICTURE) { - uint8_t ** forward_ref; - int bottom_field; - - bottom_field = (picture->picture_structure == BOTTOM_FIELD); - picture->dmv_offset = bottom_field ? 1 : -1; - picture->f_motion.ref2[0] = picture->f_motion.ref[bottom_field]; - picture->f_motion.ref2[1] = picture->f_motion.ref[!bottom_field]; - picture->b_motion.ref2[0] = picture->b_motion.ref[bottom_field]; - picture->b_motion.ref2[1] = picture->b_motion.ref[!bottom_field]; - - forward_ref = forward_reference_frame->base; - if (picture->second_field && (picture->picture_coding_type != B_TYPE)) - forward_ref = picture->current_frame->base; - - picture->f_motion.ref[1][0] = forward_ref[0] + (bottom_field ? 0 : picture->pitches[0]); - picture->f_motion.ref[1][1] = forward_ref[1] + (bottom_field ? 0 : picture->pitches[1]); - picture->f_motion.ref[1][2] = forward_ref[2] + (bottom_field ? 0 : picture->pitches[2]); - - picture->b_motion.ref[1][0] = - backward_reference_frame->base[0] + (bottom_field ? 0 : picture->pitches[0]); - picture->b_motion.ref[1][1] = - backward_reference_frame->base[1] + (bottom_field ? 0 : picture->pitches[1]); - picture->b_motion.ref[1][2] = - backward_reference_frame->base[2] + (bottom_field ? 0 : picture->pitches[2]); - } - - picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; - picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; - - picture->v_offset = (code - 1) * 16; - offset = (code - 1); - if (picture->current_frame->proc_slice && picture->picture_coding_type == B_TYPE) - offset = 0; - else if (picture->picture_structure != FRAME_PICTURE) - offset = 2 * offset; - - picture->dest[0] = picture->current_frame->base[0] + picture->pitches[0] * offset * 16; - picture->dest[1] = picture->current_frame->base[1] + picture->pitches[1] * offset * 8; - picture->dest[2] = picture->current_frame->base[2] + picture->pitches[2] * offset * 8; - - height = picture->coded_picture_height; - switch (picture->picture_structure) { - case BOTTOM_FIELD: - picture->dest[0] += picture->pitches[0]; - picture->dest[1] += picture->pitches[1]; - picture->dest[2] += picture->pitches[2]; - /* follow thru */ - case TOP_FIELD: - picture->pitches[0] <<= 1; - picture->pitches[1] <<= 1; - picture->pitches[2] <<= 1; - height >>= 1; - } - picture->limit_x = 2 * picture->coded_picture_width - 32; - picture->limit_y_16 = 2 * height - 32; - picture->limit_y_8 = 2 * height - 16; - picture->limit_y = height - 16; - - //TODO conversion to signed format signed format - if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && - !(picture->mc->xvmc_accel & SIGNED_INTRA)) { - //Motion Comp only unsigned intra - // original: - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); - } else { - //Motion Comp only signed intra MOTION_ACCEL+SIGNED_INTRA - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 0; - } - - picture->quantizer_scale = get_xvmc_quantizer_scale (picture); - - /* ignore intra_slice and all the extra data */ - while (bit_buf & 0x80000000) { - DUMPBITS (bit_buf, bits, 9); - NEEDBITS (bit_buf, bits, bit_ptr); - } - - /* decode initial macroblock address increment */ - offset = 0; - while (1) { - if (bit_buf >= 0x08000000) { - mba = MBA_5 + (UBITS (bit_buf, 6) - 2); - break; - } else if (bit_buf >= 0x01800000) { - mba = MBA_11 + (UBITS (bit_buf, 12) - 24); - break; - } else switch (UBITS (bit_buf, 12)) { - case 8: /* macroblock_escape */ - offset += 33; - DUMPBITS (bit_buf, bits, 11); - NEEDBITS (bit_buf, bits, bit_ptr); - continue; - case 15: /* macroblock_stuffing (MPEG1 only) */ - bit_buf &= 0xfffff; - DUMPBITS (bit_buf, bits, 11); - NEEDBITS (bit_buf, bits, bit_ptr); - continue; - default: /* error */ - return 1; - } - } - DUMPBITS (bit_buf, bits, mba->len + 1); - picture->offset = (offset + mba->mba) << 4; - - while (picture->offset - picture->coded_picture_width >= 0) { - picture->offset -= picture->coded_picture_width; - if ((picture->current_frame->proc_slice == NULL) || - (picture->picture_coding_type != B_TYPE)) { - picture->dest[0] += 16 * picture->pitches[0]; - picture->dest[1] += 8 * picture->pitches[1]; - picture->dest[2] += 8 * picture->pitches[2]; - } - picture->v_offset += 16; - } - if (picture->v_offset > picture->limit_y) - return 1; - - return 0; -#undef bit_buf -#undef bits -#undef bit_ptr -} - -void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer) -{ -#define bit_buf (picture->bitstream_buf) -#define bits (picture->bitstream_bits) -#define bit_ptr (picture->bitstream_ptr) - cpu_state_t cpu_state; - xine_xvmc_t *xvmc = (xine_xvmc_t *) picture->current_frame->accel_data; - - if (1 == code) { - accel->xvmc_last_slice_code = 0; - } - if ((code != accel->xvmc_last_slice_code + 1) && - (code != accel->xvmc_last_slice_code)) - return; - - bitstream_init (picture, buffer); - - if (slice_xvmc_init (picture, code)) - return; - - if (mpeg2_cpu_state_save) - mpeg2_cpu_state_save (&cpu_state); - - while (1) { - int macroblock_modes; - int mba_inc; - const MBAtab * mba; - - NEEDBITS (bit_buf, bits, bit_ptr); - - macroblock_modes = get_xvmc_macroblock_modes (picture); //macroblock_modes() - picture->XvMC_mb_type = macroblock_modes & 0x1F; - picture->XvMC_dct_type = (macroblock_modes & DCT_TYPE_INTERLACED)>>5; - picture->XvMC_motion_type = (macroblock_modes & MOTION_TYPE_MASK)>>6; - - picture->XvMC_x = picture->offset/16; - picture->XvMC_y = picture->v_offset/16; - - if((picture->XvMC_x == 0) && (picture->XvMC_y == 0)) { - picture->XvMC_mv_field_sel[0][0] = - picture->XvMC_mv_field_sel[1][0] = - picture->XvMC_mv_field_sel[0][1] = - picture->XvMC_mv_field_sel[1][1] = 0; - } - - picture->XvMC_cbp = 0x3f; //TODO set for intra 4:2:0 6 blocks yyyyuv all enabled - - /* maybe integrate MACROBLOCK_QUANT test into get_xvmc_macroblock_modes ? */ - if (macroblock_modes & MACROBLOCK_QUANT) - picture->quantizer_scale = get_xvmc_quantizer_scale (picture); - if (macroblock_modes & MACROBLOCK_INTRA) { - - int DCT_offset, DCT_stride; - int offset; - uint8_t * dest_y; - - if (picture->concealment_motion_vectors) { - if (picture->picture_structure == FRAME_PICTURE) - motion_fr_conceal (picture); - else - motion_fi_conceal (picture); - } else { - picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; - picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; - } - - if (macroblock_modes & DCT_TYPE_INTERLACED) { - DCT_offset = picture->pitches[0]; - DCT_stride = picture->pitches[0] * 2; - } else { - DCT_offset = picture->pitches[0] * 8; - DCT_stride = picture->pitches[0]; - } - offset = picture->offset; - dest_y = picture->dest[0] + offset; - // unravaled loop of 6 block(i) calls in macroblock() - slice_xvmc_intra_DCT (picture, 0, dest_y, DCT_stride); - slice_xvmc_intra_DCT (picture, 0, dest_y + 8, DCT_stride); - slice_xvmc_intra_DCT (picture, 0, dest_y + DCT_offset, DCT_stride); - slice_xvmc_intra_DCT (picture, 0, dest_y + DCT_offset + 8, DCT_stride); - slice_xvmc_intra_DCT (picture, 1, picture->dest[1] + (offset >> 1), - picture->pitches[1]); - slice_xvmc_intra_DCT (picture, 2, picture->dest[2] + (offset >> 1), - picture->pitches[2]); - - if (picture->picture_coding_type == D_TYPE) { - NEEDBITS (bit_buf, bits, bit_ptr); - DUMPBITS (bit_buf, bits, 1); - } - } else { - picture->XvMC_cbp = 0; - - if (picture->picture_structure == FRAME_PICTURE) - switch (macroblock_modes & MOTION_TYPE_MASK) { - case MC_FRAME: - if (picture->mpeg1) { - MOTION_CALL (motion_mp1, macroblock_modes); - } else { - MOTION_CALL (motion_fr_frame, macroblock_modes); - } - break; - - case MC_FIELD: - //MOTION_CALL (motion_fr_field, macroblock_modes); - - if ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD) - motion_fr_field(picture, &(picture->f_motion), - mpeg2_mc.put,0); - if ((macroblock_modes) & MACROBLOCK_MOTION_BACKWARD) - motion_fr_field(picture, &(picture->b_motion), - ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD ? - mpeg2_mc.avg : mpeg2_mc.put),1); - - break; - - case MC_DMV: - MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); - break; - - case 0: - /* non-intra mb without forward mv in a P picture */ - picture->f_motion.pmv[0][0] = 0; - picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = 0; - picture->f_motion.pmv[1][1] = 0; - // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); - break; - } - else - switch (macroblock_modes & MOTION_TYPE_MASK) { - case MC_FIELD: - MOTION_CALL (motion_fi_field, macroblock_modes); - break; - - case MC_16X8: - MOTION_CALL (motion_fi_16x8, macroblock_modes); - break; - - case MC_DMV: - MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); - break; - - case 0: - /* non-intra mb without forward mv in a P picture */ - picture->f_motion.pmv[0][0] = 0; - picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = 0; - picture->f_motion.pmv[1][1] = 0; - // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); - break; - } - - if (macroblock_modes & MACROBLOCK_PATTERN) { - int coded_block_pattern; - int DCT_offset, DCT_stride; - int offset; - uint8_t * dest_y; - - if (macroblock_modes & DCT_TYPE_INTERLACED) { - DCT_offset = picture->pitches[0]; - DCT_stride = picture->pitches[0] * 2; - } else { - DCT_offset = picture->pitches[0] * 8; - DCT_stride = picture->pitches[0]; - } - - picture->XvMC_cbp = coded_block_pattern = get_xvmc_coded_block_pattern (picture); - offset = picture->offset; - dest_y = picture->dest[0] + offset; - // TODO optimize not fully used for idct accel only mc. - if (coded_block_pattern & 0x20) - slice_xvmc_non_intra_DCT (picture, dest_y, DCT_stride); // cc0 luma 0 - if (coded_block_pattern & 0x10) - slice_xvmc_non_intra_DCT (picture, dest_y + 8, DCT_stride); // cc0 luma 1 - if (coded_block_pattern & 0x08) - slice_xvmc_non_intra_DCT (picture, dest_y + DCT_offset, - DCT_stride); // cc0 luma 2 - if (coded_block_pattern & 0x04) - slice_xvmc_non_intra_DCT (picture, dest_y + DCT_offset + 8, - DCT_stride); // cc0 luma 3 - if (coded_block_pattern & 0x2) - slice_xvmc_non_intra_DCT (picture, - picture->dest[1] + (offset >> 1), - picture->pitches[1]); // cc1 croma - if (coded_block_pattern & 0x1) - slice_xvmc_non_intra_DCT (picture, - picture->dest[2] + (offset >> 1), - picture->pitches[2]); // cc2 croma - } - - if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && - !(picture->mc->xvmc_accel & SIGNED_INTRA)) { - // original: - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; - - } else { // MOTION_ACCEL+SIGNED_INTRA - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 0; - } - - } - xvmc->proc_macro_block(picture->XvMC_x, picture->XvMC_y, - picture->XvMC_mb_type, - picture->XvMC_motion_type, - picture->XvMC_mv_field_sel, - picture->XvMC_dmvector, - picture->XvMC_cbp, - picture->XvMC_dct_type, - picture->current_frame, - picture->forward_reference_frame, - picture->backward_reference_frame, - picture->picture_structure, - picture->second_field, - picture->f_motion.pmv, - picture->b_motion.pmv); - - - NEXT_MACROBLOCK; - - NEEDBITS (bit_buf, bits, bit_ptr); - mba_inc = 0; - while (1) { - if (bit_buf >= 0x10000000) { - mba = MBA_5 + (UBITS (bit_buf, 5) - 2); - break; - } else if (bit_buf >= 0x03000000) { - mba = MBA_11 + (UBITS (bit_buf, 11) - 24); - break; - } else switch (UBITS (bit_buf, 11)) { - case 8: /* macroblock_escape */ - mba_inc += 33; - /* pass through */ - case 15: /* macroblock_stuffing (MPEG1 only) */ - DUMPBITS (bit_buf, bits, 11); - NEEDBITS (bit_buf, bits, bit_ptr); - continue; - default: /* end of slice, or error */ - if (mpeg2_cpu_state_restore) - mpeg2_cpu_state_restore (&cpu_state); - accel->xvmc_last_slice_code = code; - return; - } - } - DUMPBITS (bit_buf, bits, mba->len); - mba_inc += mba->mba; - if (mba_inc) { - //TODO conversion to signed format signed format - if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && - !(picture->mc->xvmc_accel & SIGNED_INTRA)) { - // original: - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; - } else { // MOTION_ACCEL+SIGNED_INTRA - picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = - picture->dc_dct_pred[2] = 0; - } - - picture->XvMC_cbp = 0; - if (picture->picture_coding_type == P_TYPE) { - picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; - picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - - do { - if(picture->mc->xvmc_accel) { - - /* derive motion_type */ - if(picture->picture_structure == FRAME_PICTURE) { - picture->XvMC_motion_type = XINE_MC_FRAME; - } else { - picture->XvMC_motion_type = XINE_MC_FIELD; - /* predict from field of same parity */ - picture->XvMC_mv_field_sel[0][0] = - picture->XvMC_mv_field_sel[0][1] = - (picture->picture_structure==BOTTOM_FIELD); - } - picture->XvMC_mb_type = macroblock_modes & 0x1E; - picture->XvMC_x = picture->offset/16; - picture->XvMC_y = picture->v_offset/16; - - xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y, - picture->XvMC_mb_type, - picture->XvMC_motion_type, - picture->XvMC_mv_field_sel, - picture->XvMC_dmvector, - picture->XvMC_cbp, - picture->XvMC_dct_type, - picture->current_frame, - picture->forward_reference_frame, - picture->backward_reference_frame, - picture->picture_structure, - picture->second_field, - picture->f_motion.pmv, - picture->b_motion.pmv); - } else { - // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); - } - NEXT_MACROBLOCK; - } while (--mba_inc); - } else { - do { - if(picture->mc->xvmc_accel) { - - /* derive motion_type */ - if(picture->picture_structure == FRAME_PICTURE) { - picture->XvMC_motion_type = XINE_MC_FRAME; - } else { - picture->XvMC_motion_type = XINE_MC_FIELD; - /* predict from field of same parity */ - picture->XvMC_mv_field_sel[0][0] = - picture->XvMC_mv_field_sel[0][1] = - (picture->picture_structure==BOTTOM_FIELD); - } - - picture->XvMC_mb_type = macroblock_modes & 0x1E; - picture->XvMC_x = picture->offset/16; - picture->XvMC_y = picture->v_offset/16; - - xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y, - picture->XvMC_mb_type, - picture->XvMC_motion_type, - picture->XvMC_mv_field_sel, - picture->XvMC_dmvector, - picture->XvMC_cbp, - picture->XvMC_dct_type, - picture->current_frame, - picture->forward_reference_frame, - picture->backward_reference_frame, - picture->picture_structure, - picture->second_field, - picture->f_motion.pmv, - picture->b_motion.pmv); - } else { - MOTION_CALL (motion_reuse, macroblock_modes); - } - NEXT_MACROBLOCK; - } while (--mba_inc); - } - } - } - accel->xvmc_last_slice_code = code; -#undef bit_buf -#undef bits -#undef bit_ptr -} - diff --git a/src/libmpeg2/slice_xvmc_vld.c b/src/libmpeg2/slice_xvmc_vld.c deleted file mode 100644 index 3606cf66b..000000000 --- a/src/libmpeg2/slice_xvmc_vld.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2004 The Unichrome project. All rights reserved. - * - * This program 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, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTIES OR REPRESENTATIONS; 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. - * - * - */ - -#include -#include -#include "mpeg2.h" -#include "mpeg2_internal.h" -#include "xvmc_vld.h" - -static const uint8_t zig_zag_scan[64] ATTR_ALIGN(16) = -{ - /* Zig-Zag scan pattern */ - 0, 1, 8,16, 9, 2, 3,10, - 17,24,32,25,18,11, 4, 5, - 12,19,26,33,40,48,41,34, - 27,20,13, 6, 7,14,21,28, - 35,42,49,56,57,50,43,36, - 29,22,15,23,30,37,44,51, - 58,59,52,45,38,31,39,46, - 53,60,61,54,47,55,62,63 -}; - -static const uint8_t alternate_scan [64] ATTR_ALIGN(16) = -{ - /* Alternate scan pattern */ - 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, - 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, - 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, - 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 -}; - -void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture, - int code, uint8_t *buffer, uint32_t chunk_size, - uint8_t *chunk_buffer) - -{ - vo_frame_t - *frame = picture->current_frame; - xine_xxmc_t - *xxmc = (xine_xxmc_t *) frame->accel_data; - xine_vld_frame_t - *vft = &xxmc->vld_frame; - unsigned - mb_frame_height; - int - i; - const uint8_t * - scan_pattern; - float - ms_per_slice; - - if (1 == code && accel->xvmc_last_slice_code != 1) { - frame->bad_frame = 1; - accel->slices_per_row = 1; - accel->row_slice_count = 1; - - /* - * Check that first field went through OK. Otherwise, - * indicate bad frame. - */ - - if (picture->second_field) { - accel->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1; - xxmc->decoded = 0; - } else { - accel->xvmc_last_slice_code = 0; - } - - mb_frame_height = - (!(picture->mpeg1) && (picture->progressive_sequence)) ? - 2*((picture->coded_picture_height+31) >> 5) : - (picture->coded_picture_height+15) >> 4; - accel->xxmc_mb_pic_height = (picture->picture_structure == FRAME_PICTURE ) ? - mb_frame_height : mb_frame_height >> 1; - - ms_per_slice = 1000. / (90000. * mb_frame_height) * frame->duration; - xxmc->sleep = 1. / (ms_per_slice * 0.45); - if (xxmc->sleep < 1.) xxmc->sleep = 1.; - - if (picture->mpeg1) { - vft->mv_ranges[0][0] = picture->b_motion.f_code[0]; - vft->mv_ranges[0][1] = picture->b_motion.f_code[0]; - vft->mv_ranges[1][0] = picture->f_motion.f_code[0]; - vft->mv_ranges[1][1] = picture->f_motion.f_code[0]; - } else { - vft->mv_ranges[0][0] = picture->b_motion.f_code[0]; - vft->mv_ranges[0][1] = picture->b_motion.f_code[1]; - vft->mv_ranges[1][0] = picture->f_motion.f_code[0]; - vft->mv_ranges[1][1] = picture->f_motion.f_code[1]; - } - - vft->picture_structure = picture->picture_structure; - vft->picture_coding_type = picture->picture_coding_type; - vft->mpeg_coding = (picture->mpeg1) ? 0 : 1; - vft->progressive_sequence = picture->progressive_sequence; - vft->scan = (picture->scan == mpeg2_scan_alt); - vft->pred_dct_frame = picture->frame_pred_frame_dct; - vft->concealment_motion_vectors = - picture->concealment_motion_vectors; - vft->q_scale_type = picture->q_scale_type; - vft->intra_vlc_format = picture->intra_vlc_format; - vft->intra_dc_precision = picture->intra_dc_precision; - vft->second_field = picture->second_field; - - /* - * Translation of libmpeg2's Q-matrix layout to VLD XvMC's. - * Errors here will give - * blocky artifacts and sometimes wrong colors. - */ - - scan_pattern = (vft->scan) ? alternate_scan : zig_zag_scan; - - if ((vft->load_intra_quantizer_matrix = picture->load_intra_quantizer_matrix)) { - for (i=0; i<64; ++i) { - vft->intra_quantizer_matrix[scan_pattern[i]] = - picture->intra_quantizer_matrix[picture->scan[i]]; - } - } - - if ((vft->load_non_intra_quantizer_matrix = picture->load_non_intra_quantizer_matrix)) { - for (i=0; i<64; ++i) { - vft->non_intra_quantizer_matrix[scan_pattern[i]] = - picture->non_intra_quantizer_matrix[picture->scan[i]]; - } - } - - picture->load_intra_quantizer_matrix = 0; - picture->load_non_intra_quantizer_matrix = 0; - vft->forward_reference_frame = picture->forward_reference_frame; - vft->backward_reference_frame = picture->backward_reference_frame; - xxmc->proc_xxmc_begin( frame ); - if (xxmc->result != 0) { - accel->xvmc_last_slice_code=-1; - } - } - - if (((code == accel->xvmc_last_slice_code + 1) || - (code == accel->xvmc_last_slice_code))) { - - /* - * Send this slice to the output plugin. May stall for a long - * time in proc_slice; - */ - - frame->bad_frame = 1; - xxmc->slice_data_size = chunk_size; - xxmc->slice_data = chunk_buffer; - xxmc->slice_code = code; - - xxmc->proc_xxmc_slice( frame ); - - if (xxmc->result != 0) { - accel->xvmc_last_slice_code=-1; - return; - } - /* - * Keep track of slices. - */ - - accel->row_slice_count = (accel->xvmc_last_slice_code == code) ? - accel->row_slice_count + 1 : 1; - accel->slices_per_row = (accel->row_slice_count > accel->slices_per_row) ? - accel->row_slice_count:accel->slices_per_row; - accel->xvmc_last_slice_code = code; - - } else { - - /* - * An error has occured. - */ - - lprintf("libmpeg2: VLD XvMC: Slice error.\n"); - accel->xvmc_last_slice_code = -1; - return; - } -} - -void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code) -{ - vo_frame_t - *frame = picture->current_frame; - xine_xxmc_t - *xxmc = (xine_xxmc_t *) frame->accel_data; - - if (xxmc->decoded) return; - if (accel->xvmc_last_slice_code == -1) { - xxmc->proc_xxmc_flush( frame ); - return; - } - - if ((code != 0xff) || ((accel->xvmc_last_slice_code == - accel->xxmc_mb_pic_height) && - accel->slices_per_row == accel->row_slice_count)) { - - xxmc->proc_xxmc_flush( frame ); - - if (xxmc->result) { - accel->xvmc_last_slice_code=-1; - frame->bad_frame = 1; - return; - } - xxmc->decoded = 1; - accel->xvmc_last_slice_code = 0; - if (picture->picture_structure == 3 || picture->second_field) { - if (xxmc->result == 0) - frame->bad_frame = 0; - } - } -} diff --git a/src/libmpeg2/stats.c b/src/libmpeg2/stats.c deleted file mode 100644 index 63c701179..000000000 --- a/src/libmpeg2/stats.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * stats.c - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#include "config.h" - -#include -#include -#include - -#include "mpeg2_internal.h" - -static int debug_level = -1; - -/* Determine is debug output is required. */ -/* We could potentially have multiple levels of debug info */ -static int debug_is_on (void) -{ - char * env_var; - - if (debug_level < 0) { - env_var = getenv ("MPEG2_DEBUG"); - - if (env_var) - debug_level = 1; - else - debug_level = 0; - } - - return debug_level; -} - -static void stats_picture (uint8_t * buffer) -{ - static const char *const picture_coding_type_str [8] = { - "Invalid picture type", - "I-type", - "P-type", - "B-type", - "D (very bad)", - "Invalid","Invalid","Invalid" - }; - - int picture_coding_type; - int temporal_reference; - int vbv_delay; - - temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6); - picture_coding_type = (buffer [1] >> 3) & 7; - vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) | - (buffer[3] >> 3)) & 0xffff; - - fprintf (stderr, " (picture) %s temporal_reference %d, vbv_delay %d\n", - picture_coding_type_str [picture_coding_type], - temporal_reference, vbv_delay); -} - -static void stats_user_data (uint8_t * buffer) -{ - fprintf (stderr, " (user_data)\n"); -} - -static void stats_sequence (uint8_t * buffer) -{ - static const char *const aspect_ratio_information_str[8] = { - "Invalid Aspect Ratio", - "1:1", - "4:3", - "16:9", - "2.21:1", - "Invalid Aspect Ratio", - "Invalid Aspect Ratio", - "Invalid Aspect Ratio" - }; - static const char *const frame_rate_str[16] = { - "Invalid frame_rate_code", - "23.976", "24", "25" , "29.97", - "30" , "50", "59.94", "60" , - "Invalid frame_rate_code", "Invalid frame_rate_code", - "Invalid frame_rate_code", "Invalid frame_rate_code", - "Invalid frame_rate_code", "Invalid frame_rate_code", - "Invalid frame_rate_code" - }; - - int horizontal_size; - int vertical_size; - int aspect_ratio_information; - int frame_rate_code; - int bit_rate_value; - int vbv_buffer_size_value; - int constrained_parameters_flag; - int load_intra_quantizer_matrix; - int load_non_intra_quantizer_matrix; - - vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; - horizontal_size = vertical_size >> 12; - vertical_size &= 0xfff; - aspect_ratio_information = buffer[3] >> 4; - frame_rate_code = buffer[3] & 15; - bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6); - vbv_buffer_size_value = ((buffer[6] << 5) | (buffer[7] >> 3)) & 0x3ff; - constrained_parameters_flag = buffer[7] & 4; - load_intra_quantizer_matrix = buffer[7] & 2; - if (load_intra_quantizer_matrix) - buffer += 64; - load_non_intra_quantizer_matrix = buffer[7] & 1; - - fprintf (stderr, " (seq) %dx%d %s, %s fps, %5.0f kbps, VBV %d kB%s%s%s\n", - horizontal_size, vertical_size, - aspect_ratio_information_str [aspect_ratio_information], - frame_rate_str [frame_rate_code], - bit_rate_value * 400.0 / 1000.0, - 2 * vbv_buffer_size_value, - constrained_parameters_flag ? " , CP":"", - load_intra_quantizer_matrix ? " , Custom Intra Matrix":"", - load_non_intra_quantizer_matrix ? " , Custom Non-Intra Matrix":""); -} - -static void stats_sequence_error (uint8_t * buffer) -{ - fprintf (stderr, " (sequence_error)\n"); -} - -static void stats_sequence_end (uint8_t * buffer) -{ - fprintf (stderr, " (sequence_end)\n"); -} - -static void stats_group (uint8_t * buffer) -{ - fprintf (stderr, " (group)%s%s\n", - (buffer[4] & 0x40) ? " closed_gop" : "", - (buffer[4] & 0x20) ? " broken_link" : ""); -} - -static void stats_slice (int code, uint8_t * buffer) -{ - /* fprintf (stderr, " (slice %d)\n", code); */ -} - -static void stats_sequence_extension (uint8_t * buffer) -{ - static const char *const chroma_format_str[4] = { - "Invalid Chroma Format", - "4:2:0 Chroma", - "4:2:2 Chroma", - "4:4:4 Chroma" - }; - - int progressive_sequence; - int chroma_format; - - progressive_sequence = (buffer[1] >> 3) & 1; - chroma_format = (buffer[1] >> 1) & 3; - - fprintf (stderr, " (seq_ext) progressive_sequence %d, %s\n", - progressive_sequence, chroma_format_str [chroma_format]); -} - -static void stats_sequence_display_extension (uint8_t * buffer) -{ - fprintf (stderr, " (sequence_display_extension)\n"); -} - -static void stats_quant_matrix_extension (uint8_t * buffer) -{ - fprintf (stderr, " (quant_matrix_extension)\n"); -} - -static void stats_copyright_extension (uint8_t * buffer) -{ - fprintf (stderr, " (copyright_extension)\n"); -} - - -static void stats_sequence_scalable_extension (uint8_t * buffer) -{ - fprintf (stderr, " (sequence_scalable_extension)\n"); -} - -static void stats_picture_display_extension (uint8_t * buffer) -{ - fprintf (stderr, " (picture_display_extension)\n"); -} - -static void stats_picture_coding_extension (uint8_t * buffer) -{ - static const char *const picture_structure_str[4] = { - "Invalid Picture Structure", - "Top field", - "Bottom field", - "Frame Picture" - }; - - int f_code[2][2]; - int intra_dc_precision; - int picture_structure; - int top_field_first; - int frame_pred_frame_dct; - int concealment_motion_vectors; - int q_scale_type; - int intra_vlc_format; - int alternate_scan; - int repeat_first_field; - int progressive_frame; - - f_code[0][0] = buffer[0] & 15; - f_code[0][1] = buffer[1] >> 4; - f_code[1][0] = buffer[1] & 15; - f_code[1][1] = buffer[2] >> 4; - intra_dc_precision = (buffer[2] >> 2) & 3; - picture_structure = buffer[2] & 3; - top_field_first = buffer[3] >> 7; - frame_pred_frame_dct = (buffer[3] >> 6) & 1; - concealment_motion_vectors = (buffer[3] >> 5) & 1; - q_scale_type = (buffer[3] >> 4) & 1; - intra_vlc_format = (buffer[3] >> 3) & 1; - alternate_scan = (buffer[3] >> 2) & 1; - repeat_first_field = (buffer[3] >> 1) & 1; - progressive_frame = buffer[4] >> 7; - - fprintf (stderr, - " (pic_ext) %s\n", picture_structure_str [picture_structure]); - fprintf (stderr, - " (pic_ext) forward horizontal f_code % d, forward vertical f_code % d\n", - f_code[0][0], f_code[0][1]); - fprintf (stderr, - " (pic_ext) backward horizontal f_code % d, backward vertical f_code % d\n", - f_code[1][0], f_code[1][1]); - fprintf (stderr, - " (pic_ext) intra_dc_precision %d, top_field_first %d, frame_pred_frame_dct %d\n", - intra_dc_precision, top_field_first, frame_pred_frame_dct); - fprintf (stderr, - " (pic_ext) concealment_motion_vectors %d, q_scale_type %d, intra_vlc_format %d\n", - concealment_motion_vectors, q_scale_type, intra_vlc_format); - fprintf (stderr, - " (pic_ext) alternate_scan %d, repeat_first_field %d, progressive_frame %d\n", - alternate_scan, repeat_first_field, progressive_frame); -} - -void mpeg2_stats (int code, uint8_t * buffer) -{ - if (! (debug_is_on ())) - return; - - switch (code) { - case 0x00: - stats_picture (buffer); - break; - case 0xb2: - stats_user_data (buffer); - break; - case 0xb3: - stats_sequence (buffer); - break; - case 0xb4: - stats_sequence_error (buffer); - break; - case 0xb5: - switch (buffer[0] >> 4) { - case 1: - stats_sequence_extension (buffer); - break; - case 2: - stats_sequence_display_extension (buffer); - break; - case 3: - stats_quant_matrix_extension (buffer); - break; - case 4: - stats_copyright_extension (buffer); - break; - case 5: - stats_sequence_scalable_extension (buffer); - break; - case 7: - stats_picture_display_extension (buffer); - break; - case 8: - stats_picture_coding_extension (buffer); - break; - default: - fprintf (stderr, " (unknown extension %#x)\n", buffer[0] >> 4); - } - break; - case 0xb7: - stats_sequence_end (buffer); - break; - case 0xb8: - stats_group (buffer); - break; - default: - if (code < 0xb0) - stats_slice (code, buffer); - else - fprintf (stderr, " (unknown start code %#02x)\n", code); - } -} diff --git a/src/libmpeg2/vis.h b/src/libmpeg2/vis.h deleted file mode 100644 index 69dd49075..000000000 --- a/src/libmpeg2/vis.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * vis.h - * Copyright (C) 2003 David S. Miller - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -/* You may be asking why I hard-code the instruction opcodes and don't - * use the normal VIS assembler mnenomics for the VIS instructions. - * - * The reason is that Sun, in their infinite wisdom, decided that a binary - * using a VIS instruction will cause it to be marked (in the ELF headers) - * as doing so, and this prevents the OS from loading such binaries if the - * current cpu doesn't have VIS. There is no way to easily override this - * behavior of the assembler that I am aware of. - * - * This totally defeats what libmpeg2 is trying to do which is allow a - * single binary to be created, and then detect the availability of VIS - * at runtime. - * - * I'm not saying that tainting the binary by default is bad, rather I'm - * saying that not providing a way to override this easily unnecessarily - * ties people's hands. - * - * Thus, we do the opcode encoding by hand and output 32-bit words in - * the assembler to keep the binary from becoming tainted. - */ - -#define vis_opc_base ((0x1 << 31) | (0x36 << 19)) -#define vis_opf(X) ((X) << 5) -#define vis_sreg(X) (X) -#define vis_dreg(X) (((X)&0x1f)|((X)>>5)) -#define vis_rs1_s(X) (vis_sreg(X) << 14) -#define vis_rs1_d(X) (vis_dreg(X) << 14) -#define vis_rs2_s(X) (vis_sreg(X) << 0) -#define vis_rs2_d(X) (vis_dreg(X) << 0) -#define vis_rd_s(X) (vis_sreg(X) << 25) -#define vis_rd_d(X) (vis_dreg(X) << 25) - -#define vis_ss2s(opf,rs1,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rs2_s(rs2) | \ - vis_rd_s(rd))) - -#define vis_dd2d(opf,rs1,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_d(rs1) | \ - vis_rs2_d(rs2) | \ - vis_rd_d(rd))) - -#define vis_ss2d(opf,rs1,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rs2_s(rs2) | \ - vis_rd_d(rd))) - -#define vis_sd2d(opf,rs1,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rs2_d(rs2) | \ - vis_rd_d(rd))) - -#define vis_d2s(opf,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_d(rs2) | \ - vis_rd_s(rd))) - -#define vis_s2d(opf,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_s(rs2) | \ - vis_rd_d(rd))) - -#define vis_d12d(opf,rs1,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_d(rs1) | \ - vis_rd_d(rd))) - -#define vis_d22d(opf,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_d(rs2) | \ - vis_rd_d(rd))) - -#define vis_s12s(opf,rs1,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rd_s(rd))) - -#define vis_s22s(opf,rs2,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_s(rs2) | \ - vis_rd_s(rd))) - -#define vis_s(opf,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rd_s(rd))) - -#define vis_d(opf,rd) \ - __asm__ __volatile__ (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rd_d(rd))) - -#define vis_r2m(op,rd,mem) \ - __asm__ __volatile__ (#op "\t%%f" #rd ", [%0]" : : "r" (&(mem)) ) - -#define vis_r2m_2(op,rd,mem1,mem2) \ - __asm__ __volatile__ (#op "\t%%f" #rd ", [%0 + %1]" : : "r" (mem1), "r" (mem2) ) - -#define vis_m2r(op,mem,rd) \ - __asm__ __volatile__ (#op "\t[%0], %%f" #rd : : "r" (&(mem)) ) - -#define vis_m2r_2(op,mem1,mem2,rd) \ - __asm__ __volatile__ (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) ) - -static inline void vis_set_gsr(unsigned int _val) -{ - register unsigned int val asm("g1"); - - val = _val; - __asm__ __volatile__(".word 0xa7804000" - : : "r" (val)); -} - -#define VIS_GSR_ALIGNADDR_MASK 0x0000007 -#define VIS_GSR_ALIGNADDR_SHIFT 0 -#define VIS_GSR_SCALEFACT_MASK 0x0000078 -#define VIS_GSR_SCALEFACT_SHIFT 3 - -#define vis_ld32(mem,rs1) vis_m2r(ld, mem, rs1) -#define vis_ld32_2(mem1,mem2,rs1) vis_m2r_2(ld, mem1, mem2, rs1) -#define vis_st32(rs1,mem) vis_r2m(st, rs1, mem) -#define vis_st32_2(rs1,mem1,mem2) vis_r2m_2(st, rs1, mem1, mem2) -#define vis_ld64(mem,rs1) vis_m2r(ldd, mem, rs1) -#define vis_ld64_2(mem1,mem2,rs1) vis_m2r_2(ldd, mem1, mem2, rs1) -#define vis_st64(rs1,mem) vis_r2m(std, rs1, mem) -#define vis_st64_2(rs1,mem1,mem2) vis_r2m_2(std, rs1, mem1, mem2) - -#define vis_ldblk(mem, rd) \ -do { register void *__mem asm("g1"); \ - __mem = &(mem); \ - __asm__ __volatile__(".word 0xc1985e00 | %1" \ - : \ - : "r" (__mem), \ - "i" (vis_rd_d(rd)) \ - : "memory"); \ -} while (0) - -#define vis_stblk(rd, mem) \ -do { register void *__mem asm("g1"); \ - __mem = &(mem); \ - __asm__ __volatile__(".word 0xc1b85e00 | %1" \ - : \ - : "r" (__mem), \ - "i" (vis_rd_d(rd)) \ - : "memory"); \ -} while (0) - -#define vis_membar_storestore() \ - __asm__ __volatile__(".word 0x8143e008" : : : "memory") - -#define vis_membar_sync() \ - __asm__ __volatile__(".word 0x8143e040" : : : "memory") - -/* 16 and 32 bit partitioned addition and subtraction. The normal - * versions perform 4 16-bit or 2 32-bit additions or subtractions. - * The 's' versions perform 2 16-bit or 2 32-bit additions or - * subtractions. - */ - -#define vis_padd16(rs1,rs2,rd) vis_dd2d(0x50, rs1, rs2, rd) -#define vis_padd16s(rs1,rs2,rd) vis_ss2s(0x51, rs1, rs2, rd) -#define vis_padd32(rs1,rs2,rd) vis_dd2d(0x52, rs1, rs2, rd) -#define vis_padd32s(rs1,rs2,rd) vis_ss2s(0x53, rs1, rs2, rd) -#define vis_psub16(rs1,rs2,rd) vis_dd2d(0x54, rs1, rs2, rd) -#define vis_psub16s(rs1,rs2,rd) vis_ss2s(0x55, rs1, rs2, rd) -#define vis_psub32(rs1,rs2,rd) vis_dd2d(0x56, rs1, rs2, rd) -#define vis_psub32s(rs1,rs2,rd) vis_ss2s(0x57, rs1, rs2, rd) - -/* Pixel formatting instructions. */ - -#define vis_pack16(rs2,rd) vis_d2s( 0x3b, rs2, rd) -#define vis_pack32(rs1,rs2,rd) vis_dd2d(0x3a, rs1, rs2, rd) -#define vis_packfix(rs2,rd) vis_d2s( 0x3d, rs2, rd) -#define vis_expand(rs2,rd) vis_s2d( 0x4d, rs2, rd) -#define vis_pmerge(rs1,rs2,rd) vis_ss2d(0x4b, rs1, rs2, rd) - -/* Partitioned multiply instructions. */ - -#define vis_mul8x16(rs1,rs2,rd) vis_sd2d(0x31, rs1, rs2, rd) -#define vis_mul8x16au(rs1,rs2,rd) vis_ss2d(0x33, rs1, rs2, rd) -#define vis_mul8x16al(rs1,rs2,rd) vis_ss2d(0x35, rs1, rs2, rd) -#define vis_mul8sux16(rs1,rs2,rd) vis_dd2d(0x36, rs1, rs2, rd) -#define vis_mul8ulx16(rs1,rs2,rd) vis_dd2d(0x37, rs1, rs2, rd) -#define vis_muld8sux16(rs1,rs2,rd) vis_ss2d(0x38, rs1, rs2, rd) -#define vis_muld8ulx16(rs1,rs2,rd) vis_ss2d(0x39, rs1, rs2, rd) - -/* Alignment instructions. */ - -static inline void *vis_alignaddr(void *_ptr) -{ - register void *ptr asm("g1"); - - ptr = _ptr; - - __asm__ __volatile__(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x18) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(1))); - - return ptr; -} - -static inline void vis_alignaddr_g0(void *_ptr) -{ - register void *ptr asm("g1"); - - ptr = _ptr; - - __asm__ __volatile__(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x18) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(0))); -} - -static inline void *vis_alignaddrl(void *_ptr) -{ - register void *ptr asm("g1"); - - ptr = _ptr; - - __asm__ __volatile__(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x19) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(1))); - - return ptr; -} - -static inline void vis_alignaddrl_g0(void *_ptr) -{ - register void *ptr asm("g1"); - - ptr = _ptr; - - __asm__ __volatile__(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x19) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(0))); -} - -#define vis_faligndata(rs1,rs2,rd) vis_dd2d(0x48, rs1, rs2, rd) - -/* Logical operate instructions. */ - -#define vis_fzero(rd) vis_d( 0x60, rd) -#define vis_fzeros(rd) vis_s( 0x61, rd) -#define vis_fone(rd) vis_d( 0x7e, rd) -#define vis_fones(rd) vis_s( 0x7f, rd) -#define vis_src1(rs1,rd) vis_d12d(0x74, rs1, rd) -#define vis_src1s(rs1,rd) vis_s12s(0x75, rs1, rd) -#define vis_src2(rs2,rd) vis_d22d(0x78, rs2, rd) -#define vis_src2s(rs2,rd) vis_s22s(0x79, rs2, rd) -#define vis_not1(rs1,rd) vis_d12d(0x6a, rs1, rd) -#define vis_not1s(rs1,rd) vis_s12s(0x6b, rs1, rd) -#define vis_not2(rs2,rd) vis_d22d(0x66, rs2, rd) -#define vis_not2s(rs2,rd) vis_s22s(0x67, rs2, rd) -#define vis_or(rs1,rs2,rd) vis_dd2d(0x7c, rs1, rs2, rd) -#define vis_ors(rs1,rs2,rd) vis_ss2s(0x7d, rs1, rs2, rd) -#define vis_nor(rs1,rs2,rd) vis_dd2d(0x62, rs1, rs2, rd) -#define vis_nors(rs1,rs2,rd) vis_ss2s(0x63, rs1, rs2, rd) -#define vis_and(rs1,rs2,rd) vis_dd2d(0x70, rs1, rs2, rd) -#define vis_ands(rs1,rs2,rd) vis_ss2s(0x71, rs1, rs2, rd) -#define vis_nand(rs1,rs2,rd) vis_dd2d(0x6e, rs1, rs2, rd) -#define vis_nands(rs1,rs2,rd) vis_ss2s(0x6f, rs1, rs2, rd) -#define vis_xor(rs1,rs2,rd) vis_dd2d(0x6c, rs1, rs2, rd) -#define vis_xors(rs1,rs2,rd) vis_ss2s(0x6d, rs1, rs2, rd) -#define vis_xnor(rs1,rs2,rd) vis_dd2d(0x72, rs1, rs2, rd) -#define vis_xnors(rs1,rs2,rd) vis_ss2s(0x73, rs1, rs2, rd) -#define vis_ornot1(rs1,rs2,rd) vis_dd2d(0x7a, rs1, rs2, rd) -#define vis_ornot1s(rs1,rs2,rd) vis_ss2s(0x7b, rs1, rs2, rd) -#define vis_ornot2(rs1,rs2,rd) vis_dd2d(0x76, rs1, rs2, rd) -#define vis_ornot2s(rs1,rs2,rd) vis_ss2s(0x77, rs1, rs2, rd) -#define vis_andnot1(rs1,rs2,rd) vis_dd2d(0x68, rs1, rs2, rd) -#define vis_andnot1s(rs1,rs2,rd) vis_ss2s(0x69, rs1, rs2, rd) -#define vis_andnot2(rs1,rs2,rd) vis_dd2d(0x64, rs1, rs2, rd) -#define vis_andnot2s(rs1,rs2,rd) vis_ss2s(0x65, rs1, rs2, rd) - -/* Pixel component distance. */ - -#define vis_pdist(rs1,rs2,rd) vis_dd2d(0x3e, rs1, rs2, rd) diff --git a/src/libmpeg2/vlc.h b/src/libmpeg2/vlc.h deleted file mode 100644 index 65de9a840..000000000 --- a/src/libmpeg2/vlc.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - * vlc.h - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#define GETWORD(bit_buf,shift,bit_ptr) \ -do { \ - bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \ - bit_ptr += 2; \ -} while (0) - -static inline void bitstream_init (picture_t * picture, uint8_t * start) -{ - picture->bitstream_buf = - (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3]; - picture->bitstream_ptr = start + 4; - picture->bitstream_bits = -16; -} - -/* make sure that there are at least 16 valid bits in bit_buf */ -#define NEEDBITS(bit_buf,bits,bit_ptr) \ -do { \ - if (bits > 0) { \ - GETWORD (bit_buf, bits, bit_ptr); \ - bits -= 16; \ - } \ -} while (0) - -/* remove num valid bits from bit_buf */ -#define DUMPBITS(bit_buf,bits,num) \ -do { \ - bit_buf <<= (num); \ - bits += (num); \ -} while (0) - -/* take num bits from the high part of bit_buf and zero extend them */ -#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num))) - -/* take num bits from the high part of bit_buf and sign extend them */ -#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num))) - -typedef struct { - uint8_t modes; - uint8_t len; -} MBtab; - -typedef struct { - uint8_t delta; - uint8_t len; -} MVtab; - -typedef struct { - int8_t dmv; - uint8_t len; -} DMVtab; - -typedef struct { - uint8_t cbp; - uint8_t len; -} CBPtab; - -typedef struct { - uint8_t size; - uint8_t len; -} DCtab; - -typedef struct { - uint8_t run; - uint8_t level; - uint8_t len; -} DCTtab; - -typedef struct { - uint8_t mba; - uint8_t len; -} MBAtab; - - -#define INTRA MACROBLOCK_INTRA -#define QUANT MACROBLOCK_QUANT - -static const MBtab MB_I [] = { - {INTRA|QUANT, 2}, {INTRA, 1} -}; - -#define MC MACROBLOCK_MOTION_FORWARD -#define CODED MACROBLOCK_PATTERN - -static const MBtab MB_P [] = { - {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5}, - {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3}, - {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, - {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, - {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, - {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, - {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, - {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1} -}; - -#define FWD MACROBLOCK_MOTION_FORWARD -#define BWD MACROBLOCK_MOTION_BACKWARD -#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD - -static const MBtab MB_B [] = { - {0, 0}, {INTRA|QUANT, 6}, - {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6}, - {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5}, - {INTRA, 5}, {INTRA, 5}, - {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4}, - {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, - {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, - {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, - {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, - {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, - {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, - {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, - {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, - {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, - {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, - {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, - {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, - {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2} -}; - -#undef INTRA -#undef QUANT -#undef MC -#undef CODED -#undef FWD -#undef BWD -#undef INTER - - -static const MVtab MV_4 [] = { - { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} -}; - -static const MVtab MV_10 [] = { - { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, - { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10}, - {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9}, - { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, - { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, - { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7} -}; - - -static const DMVtab DMV_2 [] = { - { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} -}; - - -static const CBPtab CBP_7 [] = { - {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7}, - {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7}, - {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6}, - {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6}, - {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, - {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5}, - {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, - {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5}, - {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5}, - {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5}, - {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, - {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, - {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5}, - {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5}, - {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5}, - {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, - {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, - {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, - {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, - {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, - {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, - {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, - {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, - {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, - {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, - {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, - {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, - {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3} -}; - -static const CBPtab CBP_9 [] = { - {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9}, - {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9}, - {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8}, - {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8}, - {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8}, - {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8}, - {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8}, - {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8}, - {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8}, - {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8}, - {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8}, - {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8}, - {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8}, - {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8}, - {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8}, - {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8} -}; - - -static const DCtab DC_lum_5 [] = { - {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, - {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, - {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5} -}; - -static const DCtab DC_chrom_5 [] = { - {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, - {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, - {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5} -}; - -static const DCtab DC_long [] = { - {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, - {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, - {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6}, - {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9} -}; - - -static const DCTtab DCT_16 [] = { - {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, - {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, - {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, - {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, - { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0}, - { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0}, - { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0}, - { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0} -}; - -static const DCTtab DCT_15 [] = { - { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15}, - { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15}, - { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15}, - { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15}, - { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14}, - { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14}, - { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14}, - { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14}, - { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14}, - { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14}, - { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14}, - { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14} -}; - -static const DCTtab DCT_13 [] = { - { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13}, - { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13}, - { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13}, - { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13}, - { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12}, - { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12}, - { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12}, - { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12}, - { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12}, - { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12}, - { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12}, - { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12} -}; - -static const DCTtab DCT_B14_10 [] = { - { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10}, - { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10} -}; - -static const DCTtab DCT_B14_8 [] = { - { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, - { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7}, - { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7}, - { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, - { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, - { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, - { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, - { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8}, - { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8} -}; - -static const DCTtab DCT_B14AC_5 [] = { - { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, - { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, - {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2} -}; - -static const DCTtab DCT_B14DC_5 [] = { - { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, - { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, - { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, - { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, - { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1} -}; - -static const DCTtab DCT_B15_10 [] = { - { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9}, - { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9} -}; - -static const DCTtab DCT_B15_8 [] = { - { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, - { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7}, - { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7}, - { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, - { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, - { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, - { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, - { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8}, - { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8}, - { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, - { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, - { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, - { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, - { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, - { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, - {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, - {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, - {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, - {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, - { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, - { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, - { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, - { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, - { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, - { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, - { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, - { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, - { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7}, - { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7}, - { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8}, - { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8} -}; - - -static const MBAtab MBA_5 [] = { - {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4}, - {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, - {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, - {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} -}; - -static const MBAtab MBA_11 [] = { - {32, 11}, {31, 11}, {30, 11}, {29, 11}, - {28, 11}, {27, 11}, {26, 11}, {25, 11}, - {24, 11}, {23, 11}, {22, 11}, {21, 11}, - {20, 10}, {20, 10}, {19, 10}, {19, 10}, - {18, 10}, {18, 10}, {17, 10}, {17, 10}, - {16, 10}, {16, 10}, {15, 10}, {15, 10}, - {14, 8}, {14, 8}, {14, 8}, {14, 8}, - {14, 8}, {14, 8}, {14, 8}, {14, 8}, - {13, 8}, {13, 8}, {13, 8}, {13, 8}, - {13, 8}, {13, 8}, {13, 8}, {13, 8}, - {12, 8}, {12, 8}, {12, 8}, {12, 8}, - {12, 8}, {12, 8}, {12, 8}, {12, 8}, - {11, 8}, {11, 8}, {11, 8}, {11, 8}, - {11, 8}, {11, 8}, {11, 8}, {11, 8}, - {10, 8}, {10, 8}, {10, 8}, {10, 8}, - {10, 8}, {10, 8}, {10, 8}, {10, 8}, - { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, - { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, - { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, - { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, - { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, - { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, - { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, - { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, - { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, - { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7} -}; diff --git a/src/libmpeg2/xine_mpeg2_decoder.c b/src/libmpeg2/xine_mpeg2_decoder.c deleted file mode 100644 index 3a3e28452..000000000 --- a/src/libmpeg2/xine_mpeg2_decoder.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stuff needed to turn libmpeg2 into a xine decoder plugin - */ - - -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "mpeg2_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include "mpeg2.h" -#include "mpeg2_internal.h" -#include - -typedef struct { - video_decoder_class_t decoder_class; -} mpeg2_class_t; - - -typedef struct mpeg2dec_decoder_s { - video_decoder_t video_decoder; - mpeg2dec_t mpeg2; - mpeg2_class_t *class; - xine_stream_t *stream; -} mpeg2dec_decoder_t; - -static void mpeg2dec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; - - lprintf ("decode_data, flags=0x%08x ...\n", buf->decoder_flags); - - /* handle aspect hints from xine-dvdnav */ - if (buf->decoder_flags & BUF_FLAG_SPECIAL) { - if (buf->decoder_info[1] == BUF_SPECIAL_ASPECT) { - this->mpeg2.force_aspect = buf->decoder_info[2]; - if (buf->decoder_info[3] == 0x1 && buf->decoder_info[2] == 3) - /* letterboxing is denied, we have to do pan&scan */ - this->mpeg2.force_pan_scan = 1; - else - this->mpeg2.force_pan_scan = 0; - } - return; - } - - if (buf->decoder_flags & BUF_FLAG_PREVIEW) { - mpeg2_find_sequence_header (&this->mpeg2, buf->content, buf->content + buf->size); - } else { - - mpeg2_decode_data (&this->mpeg2, buf->content, buf->content + buf->size, - buf->pts); - } - - lprintf ("decode_data...done\n"); -} - -static void mpeg2dec_flush (video_decoder_t *this_gen) { - mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; - - lprintf ("flush\n"); - - mpeg2_flush (&this->mpeg2); -} - -static void mpeg2dec_reset (video_decoder_t *this_gen) { - mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; - - mpeg2_reset (&this->mpeg2); -} - -static void mpeg2dec_discontinuity (video_decoder_t *this_gen) { - mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; - - mpeg2_discontinuity (&this->mpeg2); -} - -static void mpeg2dec_dispose (video_decoder_t *this_gen) { - - mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; - - lprintf ("close\n"); - - mpeg2_close (&this->mpeg2); - - 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) { - mpeg2dec_decoder_t *this ; - - this = (mpeg2dec_decoder_t *) xine_xmalloc (sizeof (mpeg2dec_decoder_t)); - - this->video_decoder.decode_data = mpeg2dec_decode_data; - this->video_decoder.flush = mpeg2dec_flush; - this->video_decoder.reset = mpeg2dec_reset; - this->video_decoder.discontinuity = mpeg2dec_discontinuity; - this->video_decoder.dispose = mpeg2dec_dispose; - this->stream = stream; - this->class = (mpeg2_class_t *) class_gen; - this->mpeg2.stream = stream; - - mpeg2_init (&this->mpeg2, stream->video_out); - (stream->video_out->open) (stream->video_out, stream); - this->mpeg2.force_aspect = this->mpeg2.force_pan_scan = 0; - - return &this->video_decoder; -} - -/* - * mpeg2 plugin class - */ -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.identifier = "mpeg2dec"; - this->decoder_class.description = N_("mpeg2 based video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 }; - -static const decoder_info_t dec_info_mpeg2 = { - supported_types, /* supported types */ - 7 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "mpeg2", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libmpeg2/xvmc.h b/src/libmpeg2/xvmc.h deleted file mode 100644 index 5d61bcf83..000000000 --- a/src/libmpeg2/xvmc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * mpeg2_internal.h - * Copyright (C) 2000-2002 Michel Lespinasse - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * mpeg2dec 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. - * - * mpeg2dec 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 - */ - -#ifndef _XVMC_H -#include "libmpeg2_accel.h" - -/* slice_xvmc.c */ - -void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer); -void xvmc_setup_scan_ptable( void ); - -#endif diff --git a/src/libmpeg2/xvmc_vld.h b/src/libmpeg2/xvmc_vld.h deleted file mode 100644 index 561d1789d..000000000 --- a/src/libmpeg2/xvmc_vld.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2004 The Unichrome project. All rights reserved. - * - * This program 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, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTIES OR REPRESENTATIONS; 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. - * - * - */ - -#ifndef _XVMC_VLD_H -#define _XVMC_VLD_H - -#include "accel_xvmc.h" -#include "xvmc.h" - -extern void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture, - int code, uint8_t *buffer, uint32_t chunk_size, - uint8_t *chunk_buffer); -extern void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code); - - -#endif diff --git a/src/video_dec/Makefile.am b/src/video_dec/Makefile.am index 321d70c1f..91246eb4d 100644 --- a/src/video_dec/Makefile.am +++ b/src/video_dec/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = libmpeg2 + include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) diff --git a/src/video_dec/libmpeg2/Makefile.am b/src/video_dec/libmpeg2/Makefile.am new file mode 100644 index 000000000..d772f0e09 --- /dev/null +++ b/src/video_dec/libmpeg2/Makefile.am @@ -0,0 +1,32 @@ +include $(top_srcdir)/misc/Makefile.common + +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) +AM_LDFLAGS = $(xineplug_ldflags) + +noinst_HEADERS = vlc.h mpeg2.h xvmc.h xvmc_vld.h mpeg2_internal.h idct_mlib.h vis.h \ + libmpeg2_accel.h + +xineplug_LTLIBRARIES = xineplug_decode_mpeg2.la + +xineplug_decode_mpeg2_la_SOURCES = \ + cpu_state.c \ + decode.c \ + header.c \ + idct.c \ + idct_altivec.c \ + idct_mlib.c \ + idct_mmx.c \ + motion_comp.c \ + motion_comp_altivec.c \ + motion_comp_mmx.c \ + motion_comp_mlib.c \ + motion_comp_vis.c \ + slice.c \ + slice_xvmc.c \ + slice_xvmc_vld.c \ + stats.c \ + xine_mpeg2_decoder.c \ + libmpeg2_accel.c + +xineplug_decode_mpeg2_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) -lm +xineplug_decode_mpeg2_la_CFLAGS = $(AM_CFLAGS) $(MLIB_CFLAGS) diff --git a/src/video_dec/libmpeg2/cpu_state.c b/src/video_dec/libmpeg2/cpu_state.c new file mode 100644 index 000000000..12963644c --- /dev/null +++ b/src/video_dec/libmpeg2/cpu_state.c @@ -0,0 +1,183 @@ +/* + * cpu_state.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "mpeg2_internal.h" +#include + +void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; +void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +static void state_restore_mmx (cpu_state_t * state) +{ + emms (); +} +#endif + +#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) + +#ifndef HOST_OS_DARWIN + +static void state_save_altivec (cpu_state_t * state) +{ + asm (" \n" + " li %r9, 16 \n" + " stvx %v20, 0, %r3 \n" + " li %r11, 32 \n" + " stvx %v21, %r9, %r3 \n" + " li %r9, 48 \n" + " stvx %v22, %r11, %r3 \n" + " li %r11, 64 \n" + " stvx %v23, %r9, %r3 \n" + " li %r9, 80 \n" + " stvx %v24, %r11, %r3 \n" + " li %r11, 96 \n" + " stvx %v25, %r9, %r3 \n" + " li %r9, 112 \n" + " stvx %v26, %r11, %r3 \n" + " li %r11, 128 \n" + " stvx %v27, %r9, %r3 \n" + " li %r9, 144 \n" + " stvx %v28, %r11, %r3 \n" + " li %r11, 160 \n" + " stvx %v29, %r9, %r3 \n" + " li %r9, 176 \n" + " stvx %v30, %r11, %r3 \n" + " stvx %v31, %r9, %r3 \n" + ); +} + +static void state_restore_altivec (cpu_state_t * state) +{ + asm (" \n" + " li %r9, 16 \n" + " lvx %v20, 0, %r3 \n" + " li %r11, 32 \n" + " lvx %v21, %r9, %r3 \n" + " li %r9, 48 \n" + " lvx %v22, %r11, %r3 \n" + " li %r11, 64 \n" + " lvx %v23, %r9, %r3 \n" + " li %r9, 80 \n" + " lvx %v24, %r11, %r3 \n" + " li %r11, 96 \n" + " lvx %v25, %r9, %r3 \n" + " li %r9, 112 \n" + " lvx %v26, %r11, %r3 \n" + " li %r11, 128 \n" + " lvx %v27, %r9, %r3 \n" + " li %r9, 144 \n" + " lvx %v28, %r11, %r3 \n" + " li %r11, 160 \n" + " lvx %v29, %r9, %r3 \n" + " li %r9, 176 \n" + " lvx %v30, %r11, %r3 \n" + " lvx %v31, %r9, %r3 \n" + ); +} + +#else /* HOST_OS_DARWIN */ + +#define LI(a,b) "li r" #a "," #b "\n\t" +#define STVX0(a,b,c) "stvx v" #a ",0,r" #c "\n\t" +#define STVX(a,b,c) "stvx v" #a ",r" #b ",r" #c "\n\t" +#define LVX0(a,b,c) "lvx v" #a ",0,r" #c "\n\t" +#define LVX(a,b,c) "lvx v" #a ",r" #b ",r" #c "\n\t" + +static void state_save_altivec (cpu_state_t * state) +{ + asm (LI (9, 16) + STVX0 (20, 0, 3) + LI (11, 32) + STVX (21, 9, 3) + LI (9, 48) + STVX (22, 11, 3) + LI (11, 64) + STVX (23, 9, 3) + LI (9, 80) + STVX (24, 11, 3) + LI (11, 96) + STVX (25, 9, 3) + LI (9, 112) + STVX (26, 11, 3) + LI (11, 128) + STVX (27, 9, 3) + LI (9, 144) + STVX (28, 11, 3) + LI (11, 160) + STVX (29, 9, 3) + LI (9, 176) + STVX (30, 11, 3) + STVX (31, 9, 3)); +} + +static void state_restore_altivec (cpu_state_t * state) +{ + asm (LI (9, 16) + LVX0 (20, 0, 3) + LI (11, 32) + LVX (21, 9, 3) + LI (9, 48) + LVX (22, 11, 3) + LI (11, 64) + LVX (23, 9, 3) + LI (9, 80) + LVX (24, 11, 3) + LI (11, 96) + LVX (25, 9, 3) + LI (9, 112) + LVX (26, 11, 3) + LI (11, 128) + LVX (27, 9, 3) + LI (9, 144) + LVX (28, 11, 3) + LI (11, 160) + LVX (29, 9, 3) + LI (9, 176) + LVX (30, 11, 3) + LVX (31, 9, 3)); +} +#endif /* HOST_OS_DARWIN */ + +#endif /* defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) */ + +void mpeg2_cpu_state_init (uint32_t mm_accel) +{ +#if defined(ARCH_X86) || defined(ARCH_X86_64) + if (mm_accel & MM_ACCEL_X86_MMX) { + mpeg2_cpu_state_restore = state_restore_mmx; + } +#endif +#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) + if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { + mpeg2_cpu_state_save = state_save_altivec; + mpeg2_cpu_state_restore = state_restore_altivec; + } +#endif +} + diff --git a/src/video_dec/libmpeg2/decode.c b/src/video_dec/libmpeg2/decode.c new file mode 100644 index 000000000..145d5f58b --- /dev/null +++ b/src/video_dec/libmpeg2/decode.c @@ -0,0 +1,1009 @@ +/* + * decode.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + * + * xine-specific version by G. Bartsch + * + */ + +#include "config.h" +#include +#include /* memcpy/memset, try to remove */ +#include +#include +#include + +#define LOG_MODULE "decode" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include +#include "libmpeg2_accel.h" + +/* +#define LOG_PAN_SCAN +*/ + +/* #define BUFFER_SIZE (224 * 1024) */ +#define BUFFER_SIZE (1194 * 1024) /* new buffer size for mpeg2dec 0.2.1 */ + +static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); + +void mpeg2_init (mpeg2dec_t * mpeg2dec, + xine_video_port_t * output) +{ + static int do_init = 1; + uint32_t mm_accel; + + if (do_init) { + do_init = 0; + mm_accel = xine_mm_accel(); + mpeg2_cpu_state_init (mm_accel); + mpeg2_idct_init (mm_accel); + mpeg2_mc_init (mm_accel); + libmpeg2_accel_scan(&mpeg2dec->accel, mpeg2_scan_norm, mpeg2_scan_alt); + } + + if( !mpeg2dec->chunk_buffer ) + mpeg2dec->chunk_buffer = xine_xmalloc_aligned (16, BUFFER_SIZE + 4, + &mpeg2dec->chunk_base); + if( !mpeg2dec->picture ) + mpeg2dec->picture = xine_xmalloc_aligned (16, sizeof (picture_t), + &mpeg2dec->picture_base); + + mpeg2dec->shift = 0xffffff00; + mpeg2dec->new_sequence = 0; + mpeg2dec->is_sequence_needed = 1; + mpeg2dec->is_wait_for_ip_frames = 2; + mpeg2dec->frames_to_drop = 0; + mpeg2dec->drop_frame = 0; + mpeg2dec->in_slice = 0; + mpeg2dec->output = output; + mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; + mpeg2dec->code = 0xb4; + mpeg2dec->seek_mode = 0; + + /* initialize AFD storage */ + mpeg2dec->afd_value_seen = XINE_VIDEO_AFD_NOT_PRESENT; + mpeg2dec->afd_value_reported = (XINE_VIDEO_AFD_NOT_PRESENT - 1); + + memset (mpeg2dec->picture, 0, sizeof (picture_t)); + + /* initialize substructures */ + mpeg2_header_state_init (mpeg2dec->picture); + + if ( output->get_capabilities(output) & VO_CAP_XXMC) { + printf("libmpeg2: output port has XxMC capability\n"); + mpeg2dec->frame_format = XINE_IMGFMT_XXMC; + } else if( output->get_capabilities(output) & VO_CAP_XVMC_MOCOMP) { + printf("libmpeg2: output port has XvMC capability\n"); + mpeg2dec->frame_format = XINE_IMGFMT_XVMC; + } else { + mpeg2dec->frame_format = XINE_IMGFMT_YV12; + } +} + +static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) +{ + static const double durations[] = { + 0, /* invalid */ + 3753.75, /* 23.976 fps */ + 3750, /* 24 fps */ + 3600, /* 25 fps */ + 3003, /* 29.97 fps */ + 3000, /* 30 fps */ + 1800, /* 50 fps */ + 1501.5, /* 59.94 fps */ + 1500, /* 60 fps */ + }; + double duration = ((unsigned) mpeg2dec->picture->frame_rate_code > 8u) + ? 0 : durations[mpeg2dec->picture->frame_rate_code]; + + duration = duration * (mpeg2dec->picture->frame_rate_ext_n + 1.0) / + (mpeg2dec->picture->frame_rate_ext_d + 1.0); + + /* this should be used to detect any special rff pattern */ + mpeg2dec->rff_pattern = mpeg2dec->rff_pattern << 1; + mpeg2dec->rff_pattern |= !!frame->repeat_first_field; + + if( ((mpeg2dec->rff_pattern & 0xff) == 0xaa || + (mpeg2dec->rff_pattern & 0xff) == 0x55) && + !mpeg2dec->picture->progressive_sequence ) { + /* special case for ntsc 3:2 pulldown */ + duration *= 5.0 / 4.0; + } + else + { + if( frame->repeat_first_field ) { + if( !mpeg2dec->picture->progressive_sequence && + frame->progressive_frame ) { + /* decoder should output 3 fields, so adjust duration to + count on this extra field time */ + duration *= 3.0 / 2.0; + } else if( mpeg2dec->picture->progressive_sequence ) { + /* for progressive sequences the output should repeat the + frame 1 or 2 times depending on top_field_first flag. */ + duration *= (frame->top_field_first) ? 3 : 2; + } + } + } + + frame->duration = (int) ceil (duration); + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, frame->duration); + /*printf("mpeg2dec: rff=%u\n",frame->repeat_first_field);*/ +} + +static double get_aspect_ratio(mpeg2dec_t *mpeg2dec) +{ + double ratio; + picture_t * picture = mpeg2dec->picture; + double mpeg1_pel_ratio[16] = {1.0 /* forbidden */, + 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, + 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ }; + + /* TODO: For slower machines the value of this function should be computed + * once and cached! + */ + + if( !picture->mpeg1 ) { + /* these hardcoded values are defined on mpeg2 standard for + * aspect ratio. other values are reserved or forbidden. */ + switch(picture->aspect_ratio_information) { + case 2: + ratio = 4.0/3.0; + break; + case 3: + ratio = 16.0/9.0; + break; + case 4: + ratio = 2.11/1.0; + break; + case 1: + default: + ratio = (double)picture->coded_picture_width/(double)picture->coded_picture_height; + break; + } + } else { + /* mpeg1 constants refer to pixel aspect ratio */ + ratio = (double)picture->coded_picture_width/(double)picture->coded_picture_height; + ratio /= mpeg1_pel_ratio[picture->aspect_ratio_information]; + } + + return ratio; +} + +static void remember_metainfo (mpeg2dec_t *mpeg2dec) { + + picture_t * picture = mpeg2dec->picture; + + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, picture->display_width); + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, picture->display_height); + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_RATIO, + ((double)10000 * get_aspect_ratio(mpeg2dec))); + + switch (mpeg2dec->picture->frame_rate_code) { + case 1: /* 23.976 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3913); + break; + case 2: /* 24 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3750); + break; + case 3: /* 25 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3600); + break; + case 4: /* 29.97 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3003); + break; + case 5: /* 30 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3000); + break; + case 6: /* 50 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1800); + break; + case 7: /* 59.94 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1525); + break; + case 8: /* 60 fps */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1509); + break; + default: + /* printf ("invalid/unknown frame rate code : %d \n", + frame->frame_rate_code); */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3000); + } + + _x_meta_info_set_utf8(mpeg2dec->stream, XINE_META_INFO_VIDEOCODEC, "MPEG (libmpeg2)"); +} + +static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, + uint8_t * buffer, int next_code) +{ + picture_t * picture; + int is_frame_done; + double ratio; + + /* wait for sequence_header_code */ + if (mpeg2dec->is_sequence_needed) { + if (code != 0xb3) { + /* printf ("libmpeg2: waiting for sequence header\n"); */ + mpeg2dec->pts = 0; + return 0; + } + } + if (mpeg2dec->is_frame_needed) { + /* printf ("libmpeg2: waiting for frame start\n"); */ + mpeg2dec->pts = 0; + if (mpeg2dec->picture->current_frame) + mpeg2dec->picture->current_frame->bad_frame = 1; + } + + mpeg2_stats (code, buffer); + + picture = mpeg2dec->picture; + is_frame_done = mpeg2dec->in_slice && ((!code) || (code >= 0xb0)); + + if (is_frame_done) + mpeg2dec->in_slice = 0; + + if (is_frame_done && picture->current_frame != NULL) { + + libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format, + picture, code); + + if (((picture->picture_structure == FRAME_PICTURE) || + (picture->second_field)) ) { + + if (mpeg2dec->drop_frame) + picture->current_frame->bad_frame = 1; + + if (picture->picture_coding_type == B_TYPE) { + if( picture->current_frame && !picture->current_frame->drawn ) { + + /* hack against wrong mpeg1 pts */ + if (picture->mpeg1) + picture->current_frame->pts = 0; + + get_frame_duration(mpeg2dec, picture->current_frame); + mpeg2dec->frames_to_drop = picture->current_frame->draw (picture->current_frame, mpeg2dec->stream); + picture->current_frame->drawn = 1; + } + } else if (picture->forward_reference_frame && !picture->forward_reference_frame->drawn) { + get_frame_duration(mpeg2dec, picture->forward_reference_frame); + mpeg2dec->frames_to_drop = picture->forward_reference_frame->draw (picture->forward_reference_frame, + mpeg2dec->stream); + picture->forward_reference_frame->drawn = 1; + } + } + } + + switch (code) { + case 0x00: /* picture_start_code */ + if (mpeg2_header_picture (picture, buffer)) { + fprintf (stderr, "bad picture header\n"); + abort(); + } + + mpeg2dec->is_frame_needed=0; + + if (!picture->second_field) { + /* find out if we want to skip this frame */ + mpeg2dec->drop_frame = 0; + + /* picture->skip_non_intra_dct = (mpeg2dec->frames_to_drop>0) ; */ + + switch (picture->picture_coding_type) { + case B_TYPE: + + lprintf ("B-Frame\n"); + + if (mpeg2dec->frames_to_drop>1) { + lprintf ("dropping b-frame because frames_to_drop==%d\n", + mpeg2dec->frames_to_drop); + mpeg2dec->drop_frame = 1; + } else if (!picture->forward_reference_frame || picture->forward_reference_frame->bad_frame + || !picture->backward_reference_frame || picture->backward_reference_frame->bad_frame) { +#ifdef LOG + printf ("libmpeg2: dropping b-frame because ref is bad ("); + if (picture->forward_reference_frame) + printf ("fw ref frame %d, bad %d;", picture->forward_reference_frame->id, + picture->forward_reference_frame->bad_frame); + else + printf ("fw ref frame not there;"); + if (picture->backward_reference_frame) + printf ("bw ref frame %d, bad %d)\n", picture->backward_reference_frame->id, + picture->backward_reference_frame->bad_frame); + else + printf ("fw ref frame not there)\n"); +#endif + mpeg2dec->drop_frame = 1; + } else if (mpeg2dec->is_wait_for_ip_frames > 0) { + lprintf("dropping b-frame because refs are invalid\n"); + mpeg2dec->drop_frame = 1; + } + break; + + case P_TYPE: + + lprintf ("P-Frame\n"); + + if (mpeg2dec->frames_to_drop>2) { + mpeg2dec->drop_frame = 1; + lprintf ("dropping p-frame because frames_to_drop==%d\n", + mpeg2dec->frames_to_drop); + } else if (!picture->backward_reference_frame || picture->backward_reference_frame->bad_frame) { + mpeg2dec->drop_frame = 1; +#ifdef LOG + if (!picture->backward_reference_frame) + printf ("libmpeg2: dropping p-frame because no ref frame\n"); + else + printf ("libmpeg2: dropping p-frame because ref %d is bad\n", picture->backward_reference_frame->id); +#endif + } else if (mpeg2dec->is_wait_for_ip_frames > 1) { + lprintf("dropping p-frame because ref is invalid\n"); + mpeg2dec->drop_frame = 1; + } else if (mpeg2dec->is_wait_for_ip_frames) + mpeg2dec->is_wait_for_ip_frames--; + + break; + + case I_TYPE: + lprintf ("I-Frame\n"); + /* for the sake of dvd menus, never drop i-frames + if (mpeg2dec->frames_to_drop>4) { + mpeg2dec->drop_frame = 1; + } + */ + + if (mpeg2dec->is_wait_for_ip_frames) + mpeg2dec->is_wait_for_ip_frames--; + + break; + } + } + + break; + + case 0xb2: /* user data code */ + process_userdata(mpeg2dec, buffer); + break; + + case 0xb3: /* sequence_header_code */ + if (mpeg2_header_sequence (picture, buffer)) { + fprintf (stderr, "bad sequence header\n"); + /* abort(); */ + break; + } + + /* reset AFD value to detect absence */ + mpeg2dec->afd_value_seen = XINE_VIDEO_AFD_NOT_PRESENT; + + /* according to ISO/IEC 13818-2, an extension start code will follow. + * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */ + picture->mpeg1 = (next_code != 0xb5); + + if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect; + + if (mpeg2dec->is_sequence_needed ) { + mpeg2dec->new_sequence = 1; + } + + if (mpeg2dec->is_sequence_needed + || (picture->aspect_ratio_information != picture->saved_aspect_ratio) + || (picture->frame_width != picture->coded_picture_width) + || (picture->frame_height != picture->coded_picture_height)) { + xine_event_t event; + xine_format_change_data_t data; + + remember_metainfo (mpeg2dec); + event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; + event.stream = mpeg2dec->stream; + event.data = &data; + event.data_length = sizeof(data); + data.width = picture->coded_picture_width; + data.height = picture->coded_picture_height; + data.aspect = picture->aspect_ratio_information; + data.pan_scan = mpeg2dec->force_pan_scan; + xine_event_send(mpeg2dec->stream, &event); + + _x_stream_info_set(mpeg2dec->stream,XINE_STREAM_INFO_VIDEO_WIDTH, + picture->display_width); + _x_stream_info_set(mpeg2dec->stream,XINE_STREAM_INFO_VIDEO_HEIGHT, + picture->display_height); + + if (picture->forward_reference_frame && + picture->forward_reference_frame != picture->current_frame && + picture->forward_reference_frame != picture->backward_reference_frame) + picture->forward_reference_frame->free (picture->forward_reference_frame); + + if (picture->backward_reference_frame && + picture->backward_reference_frame != picture->current_frame) + picture->backward_reference_frame->free (picture->backward_reference_frame); + + mpeg2dec->is_sequence_needed = 0; + picture->forward_reference_frame = NULL; + picture->backward_reference_frame = NULL; + + picture->frame_width = picture->coded_picture_width; + picture->frame_height = picture->coded_picture_height; + picture->saved_aspect_ratio = picture->aspect_ratio_information; + } + break; + + case 0xb5: /* extension_start_code */ + if (mpeg2_header_extension (picture, buffer)) { + fprintf (stderr, "bad extension\n"); + abort(); + } + break; + + case 0xb7: /* sequence end code */ +#ifdef LOG_PAN_SCAN + printf ("libmpeg2: sequence end code not handled\n"); +#endif + case 0xb8: /* group of pictures start code */ + if (mpeg2_header_group_of_pictures (picture, buffer)) { + printf ("libmpeg2: bad group of pictures\n"); + abort(); + } + default: + if ((code >= 0xb9) && (code != 0xe4)) { + printf("Not multiplexed? 0x%x\n",code); + } + if (code >= 0xb0) + break; + + /* check for AFD change once per picture */ + if (mpeg2dec->afd_value_reported != mpeg2dec->afd_value_seen) { + /* AFD data should better be stored in current_frame to have it */ + /* ready and synchronous with other data like width or height. */ + /* An AFD change should then be detected when a new frame is emitted */ + /* from the decoder to report the AFD change in display order and not */ + /* in decoding order like it happens below for now. */ + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_AFD, mpeg2dec->afd_value_seen); + lprintf ("AFD changed from %d to %d\n", mpeg2dec->afd_value_reported, mpeg2dec->afd_value_seen); + mpeg2dec->afd_value_reported = mpeg2dec->afd_value_seen; + } + + if (!(mpeg2dec->in_slice)) { + mpeg2dec->in_slice = 1; + + if (picture->second_field) { + if (picture->current_frame) + picture->current_frame->field(picture->current_frame, + picture->picture_structure); + else + mpeg2dec->drop_frame = 1; + } else { + int flags = picture->picture_structure; + + if (!picture->mpeg1) flags |= VO_INTERLACED_FLAG; + if (mpeg2dec->force_pan_scan) flags |= VO_PAN_SCAN_FLAG; + if (mpeg2dec->new_sequence) flags |= VO_NEW_SEQUENCE_FLAG; + + if ( picture->current_frame && + picture->current_frame != picture->backward_reference_frame && + picture->current_frame != picture->forward_reference_frame ) { + picture->current_frame->free (picture->current_frame); + } + if (picture->picture_coding_type == B_TYPE) { + ratio = get_aspect_ratio(mpeg2dec); + picture->current_frame = + mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out, + picture->coded_picture_width, + picture->coded_picture_height, + ratio, + mpeg2dec->frame_format, + flags); + libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, + picture, ratio, flags); + } else { + ratio = get_aspect_ratio(mpeg2dec); + picture->current_frame = + mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out, + picture->coded_picture_width, + picture->coded_picture_height, + ratio, + mpeg2dec->frame_format, + flags); + + libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, + picture, ratio, flags); + + if (picture->forward_reference_frame && + picture->forward_reference_frame != picture->backward_reference_frame) + picture->forward_reference_frame->free (picture->forward_reference_frame); + + picture->forward_reference_frame = + picture->backward_reference_frame; + picture->backward_reference_frame = picture->current_frame; + } + + if(mpeg2dec->new_sequence) + mpeg2dec->new_sequence = + libmpeg2_accel_new_sequence(&mpeg2dec->accel, mpeg2dec->frame_format, + picture); + + picture->current_frame->bad_frame = 1; + picture->current_frame->drawn = 0; + picture->current_frame->pts = mpeg2dec->pts; + picture->current_frame->top_field_first = picture->top_field_first; + picture->current_frame->repeat_first_field = picture->repeat_first_field; + picture->current_frame->progressive_frame = picture->progressive_frame; + picture->current_frame->crop_right = picture->coded_picture_width - picture->display_width; + picture->current_frame->crop_bottom = picture->coded_picture_height - picture->display_height; + + switch( picture->picture_coding_type ) { + case I_TYPE: + picture->current_frame->picture_coding_type = XINE_PICT_I_TYPE; + break; + case P_TYPE: + picture->current_frame->picture_coding_type = XINE_PICT_P_TYPE; + break; + case B_TYPE: + picture->current_frame->picture_coding_type = XINE_PICT_B_TYPE; + break; + case D_TYPE: + picture->current_frame->picture_coding_type = XINE_PICT_D_TYPE; + break; + } + + lprintf ("decoding frame %d, type %s\n", + picture->current_frame->id, picture->picture_coding_type == I_TYPE ? "I" : + picture->picture_coding_type == P_TYPE ? "P" : "B"); + mpeg2dec->pts = 0; + /*printf("Starting to decode frame %d\n",picture->current_frame->id);*/ + } + } + + if (!mpeg2dec->drop_frame && picture->current_frame != NULL) { +#ifdef DEBUG_LOG + printf("slice target %08x past %08x future %08x\n",picture->current_frame,picture->forward_reference_frame,picture->backward_reference_frame); + fflush(stdout); +#endif + libmpeg2_accel_slice(&mpeg2dec->accel, picture, code, buffer, mpeg2dec->chunk_size, + mpeg2dec->chunk_buffer); + + if( picture->v_offset > picture->limit_y || + picture->v_offset + 16 > picture->display_height ) { + picture->current_frame->bad_frame = 0; + } + } + } + + /* printf ("libmpeg2: parse_chunk %d completed\n", code); */ + return is_frame_done; +} + +static inline int find_start_code (mpeg2dec_t * mpeg2dec, + uint8_t ** current, uint8_t * limit) +{ + uint8_t * p; + + if (*current >= limit) + return 0; + if (mpeg2dec->shift == 0x00000100) + return 1; + + mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; + + if (*current >= limit) + return 0; + if (mpeg2dec->shift == 0x00000100) + return 1; + + mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; + + if (*current >= limit) + return 0; + if (mpeg2dec->shift == 0x00000100) + return 1; + + limit--; + + if (*current >= limit) { + mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; + return 0; + } + + p = *current; + + while (p < limit && (p = (uint8_t *)memchr(p, 0x01, limit - p))) { + if (p[-2] || p[-1]) + p += 3; + else { + *current = ++p; + return 1; + } + } + + *current = ++limit; + p = limit - 3; + mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; + mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; + mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; + + return 0; +} + +static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec, + uint8_t * current, uint8_t * end) +{ + uint8_t * limit; + uint8_t * data = current; + int found, bite; + + /* sequence end code 0xb7 doesn't have any data and there might be the case + * that no start code will follow this code for quite some time (e. g. in case + * of a still image. + * Therefore, return immediately with a chunk_size of 0. Setting code to 0xb4 + * will eat up any trailing garbage next time. + */ + if (mpeg2dec->code == 0xb7) { + mpeg2dec->code = 0xb4; + mpeg2dec->chunk_size = 0; + return current; + } + + limit = current + (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); + if (limit > end) + limit = end; + + found = find_start_code(mpeg2dec, ¤t, limit); + bite = current - data; + if (bite) { + xine_fast_memcpy(mpeg2dec->chunk_ptr, data, bite); + mpeg2dec->chunk_ptr += bite; + } + + if (found) { + mpeg2dec->code = *current++; + mpeg2dec->chunk_size = mpeg2dec->chunk_ptr - mpeg2dec->chunk_buffer - 3; + mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; + mpeg2dec->shift = 0xffffff00; + return current; + } + + if (current == end) + return NULL; + + /* we filled the chunk buffer without finding a start code */ + mpeg2dec->code = 0xb4; /* sequence_error_code */ + mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; + return current; +} + +int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end, + uint64_t pts) +{ + int ret; + uint8_t code; + + ret = 0; + if (mpeg2dec->seek_mode) { + mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; + mpeg2dec->code = 0xb4; + mpeg2dec->seek_mode = 0; + mpeg2dec->shift = 0xffffff00; + mpeg2dec->is_frame_needed = 1; + } + + if (pts) + mpeg2dec->pts = pts; + + while (current != end || mpeg2dec->code == 0xb7) { + code = mpeg2dec->code; + current = copy_chunk (mpeg2dec, current, end); + if (current == NULL) + break; + ret += parse_chunk (mpeg2dec, code, mpeg2dec->chunk_buffer, mpeg2dec->code); + } + + libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format, + mpeg2dec->picture, 0xff); + + return ret; +} + +void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec) { + picture_t *picture = mpeg2dec->picture; + + if( !picture ) + return; + + mpeg2dec->in_slice = 0; + mpeg2dec->pts = 0; + if ( picture->current_frame ) + picture->current_frame->pts = 0; + if ( picture->forward_reference_frame ) + picture->forward_reference_frame->pts = 0; + if ( picture->backward_reference_frame ) + picture->backward_reference_frame->pts = 0; + + libmpeg2_accel_discontinuity(&mpeg2dec->accel, mpeg2dec->frame_format, picture); +} + +void mpeg2_reset (mpeg2dec_t * mpeg2dec) { + + picture_t *picture = mpeg2dec->picture; + + if( !picture ) + return; + + mpeg2_discontinuity(mpeg2dec); + + if( !picture->mpeg1 ) { + mpeg2dec->is_wait_for_ip_frames = 2; + + /* mark current frames as bad so they won't make to screen */ + if ( picture->current_frame ) + picture->current_frame->bad_frame=1; + if (picture->forward_reference_frame ) + picture->forward_reference_frame->bad_frame=1; + if (picture->backward_reference_frame) + picture->backward_reference_frame->bad_frame=1; + + } else { + /* to free reference frames one also needs to fix slice.c to + * abort when they are NULL. unfortunately it seems to break + * DVD menus. + * + * ...so let's do this for mpeg-1 only :) + */ + if ( picture->current_frame && + picture->current_frame != picture->backward_reference_frame && + picture->current_frame != picture->forward_reference_frame ) + picture->current_frame->free (picture->current_frame); + picture->current_frame = NULL; + + if (picture->forward_reference_frame && + picture->forward_reference_frame != picture->backward_reference_frame) + picture->forward_reference_frame->free (picture->forward_reference_frame); + picture->forward_reference_frame = NULL; + + if (picture->backward_reference_frame) + picture->backward_reference_frame->free (picture->backward_reference_frame); + picture->backward_reference_frame = NULL; + } + + mpeg2dec->in_slice = 0; + mpeg2dec->seek_mode = 1; + +} + +void mpeg2_flush (mpeg2dec_t * mpeg2dec) { + + picture_t *picture = mpeg2dec->picture; + + if (!picture) + return; + + if (picture->current_frame && !picture->current_frame->drawn && + !picture->current_frame->bad_frame) { + + lprintf ("blasting out current frame %d on flush\n", + picture->current_frame->id); + + picture->current_frame->drawn = 1; + get_frame_duration(mpeg2dec, picture->current_frame); + + picture->current_frame->pts = 0; + picture->current_frame->draw(picture->current_frame, mpeg2dec->stream); + } + +} + +void mpeg2_close (mpeg2dec_t * mpeg2dec) +{ + picture_t *picture = mpeg2dec->picture; + + /* + { + static uint8_t finalizer[] = {0,0,1,0xb4}; + mpeg2_decode_data (mpeg2dec, finalizer, finalizer+4, 0); + } + */ + + /* + dont remove any picture->*->free() below. doing so will cause buffer + leak, and we only have about 15 of them. + */ + + if ( picture->current_frame ) { + if( !picture->current_frame->drawn ) { + lprintf ("blasting out current frame on close\n"); + picture->current_frame->pts = 0; + get_frame_duration(mpeg2dec, picture->current_frame); + picture->current_frame->draw (picture->current_frame, mpeg2dec->stream); + picture->current_frame->drawn = 1; + } + + if( picture->current_frame != picture->backward_reference_frame && + picture->current_frame != picture->forward_reference_frame ) { + picture->current_frame->free (picture->current_frame); + } + picture->current_frame = NULL; + } + + if (picture->forward_reference_frame && + picture->forward_reference_frame != picture->backward_reference_frame) { + picture->forward_reference_frame->free (picture->forward_reference_frame); + picture->forward_reference_frame = NULL; + } + + if (picture->backward_reference_frame) { + if( !picture->backward_reference_frame->drawn) { + lprintf ("blasting out backward reference frame on close\n"); + picture->backward_reference_frame->pts = 0; + get_frame_duration(mpeg2dec, picture->backward_reference_frame); + picture->backward_reference_frame->draw (picture->backward_reference_frame, mpeg2dec->stream); + picture->backward_reference_frame->drawn = 1; + } + picture->backward_reference_frame->free (picture->backward_reference_frame); + picture->backward_reference_frame = NULL; + } + + if ( mpeg2dec->chunk_buffer ) { + free (mpeg2dec->chunk_base); + mpeg2dec->chunk_buffer = NULL; + } + + if ( mpeg2dec->picture ) { + free (mpeg2dec->picture_base); + mpeg2dec->picture = NULL; + } + + if ( mpeg2dec->cc_dec) { + /* dispose the closed caption decoder */ + mpeg2dec->cc_dec->dispose(mpeg2dec->cc_dec); + mpeg2dec->cc_dec = NULL; + } +} + +void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec, + uint8_t * current, uint8_t * end){ + + uint8_t code, next_code; + picture_t *picture = mpeg2dec->picture; + + mpeg2dec->seek_mode = 1; + + while (current != end) { + code = mpeg2dec->code; + current = copy_chunk (mpeg2dec, current, end); + if (current == NULL) + return ; + next_code = mpeg2dec->code; + + /* printf ("looking for sequence header... %02x\n", code); */ + + mpeg2_stats (code, mpeg2dec->chunk_buffer); + + if (code == 0xb3) { /* sequence_header_code */ + if (mpeg2_header_sequence (picture, mpeg2dec->chunk_buffer)) { + printf ("libmpeg2: bad sequence header\n"); + continue; + } + + /* according to ISO/IEC 13818-2, an extension start code will follow. + * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */ + picture->mpeg1 = (next_code != 0xb5); + + if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect; + + if (mpeg2dec->is_sequence_needed) { + xine_event_t event; + xine_format_change_data_t data; + + mpeg2dec->new_sequence = 1; + + mpeg2dec->is_sequence_needed = 0; + picture->frame_width = picture->coded_picture_width; + picture->frame_height = picture->coded_picture_height; + + remember_metainfo (mpeg2dec); + + event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; + event.stream = mpeg2dec->stream; + event.data = &data; + event.data_length = sizeof(data); + data.width = picture->coded_picture_width; + data.height = picture->coded_picture_height; + data.aspect = picture->aspect_ratio_information; + data.pan_scan = mpeg2dec->force_pan_scan; + xine_event_send(mpeg2dec->stream, &event); + + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, + picture->display_width); + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, + picture->display_height); + } + } else if (code == 0xb5) { /* extension_start_code */ + if (mpeg2_header_extension (picture, mpeg2dec->chunk_buffer)) { + printf ("libmpeg2: bad extension\n"); + continue ; + } + } + } +} + +/* Find the end of the userdata field in an MPEG-2 stream */ +static uint8_t *find_end(uint8_t *buffer) +{ + uint8_t *current = buffer; + while(1) { + if (current[0] == 0 && current[1] == 0 && current[2] == 1) + break; + current++; + } + return current; +} + +static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer) +{ + /* check if user data denotes closed captions */ + if (buffer[0] == 'C' && buffer[1] == 'C') { + + if (!mpeg2dec->cc_dec) { + xine_event_t event; + xine_format_change_data_t data; + + /* open the closed caption decoder first */ + mpeg2dec->cc_dec = _x_get_spu_decoder(mpeg2dec->stream, (BUF_SPU_CC >> 16) & 0xff); + + /* send a frame format event so that the CC decoder knows the initial image size */ + event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; + event.stream = mpeg2dec->stream; + event.data = &data; + event.data_length = sizeof(data); + data.width = mpeg2dec->picture->coded_picture_width; + data.height = mpeg2dec->picture->coded_picture_height; + data.aspect = mpeg2dec->picture->aspect_ratio_information; + data.pan_scan = mpeg2dec->force_pan_scan; + xine_event_send(mpeg2dec->stream, &event); + + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, + mpeg2dec->picture->display_width); + _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, + mpeg2dec->picture->display_height); + } + + if (mpeg2dec->cc_dec) { + buf_element_t buf; + + buf.type = BUF_SPU_CC; + buf.content = &buffer[2]; + buf.pts = mpeg2dec->pts; + buf.size = find_end(buffer) - &buffer[2]; + buf.decoder_flags = 0; + + mpeg2dec->cc_dec->decode_data(mpeg2dec->cc_dec, &buf); + } + } + /* check Active Format Description ETSI TS 101 154 V1.5.1 */ + else if (buffer[0] == 0x44 && buffer[1] == 0x54 && buffer[2] == 0x47 && buffer[3] == 0x31) + mpeg2dec->afd_value_seen = (buffer[4] & 0x40) ? (buffer[5] & 0x0f) : XINE_VIDEO_AFD_NOT_PRESENT; +} diff --git a/src/video_dec/libmpeg2/header.c b/src/video_dec/libmpeg2/header.c new file mode 100644 index 000000000..12ba0ff8a --- /dev/null +++ b/src/video_dec/libmpeg2/header.c @@ -0,0 +1,411 @@ +/* + * header.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/* +#define LOG_PAN_SCAN +*/ + +#include "config.h" + +#include /* For printf debugging */ +#include + +#include "mpeg2_internal.h" +#include + +/* default intra quant matrix, in zig-zag order */ +static const uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = { + 8, + 16, 16, + 19, 16, 19, + 22, 22, 22, 22, + 22, 22, 26, 24, 26, + 27, 27, 27, 26, 26, 26, + 26, 27, 27, 27, 29, 29, 29, + 34, 34, 34, 29, 29, 29, 27, 27, + 29, 29, 32, 32, 34, 34, 37, + 38, 37, 35, 35, 34, 35, + 38, 38, 40, 40, 40, + 48, 48, 46, 46, + 56, 56, 58, + 69, 69, + 83 +}; + +uint8_t mpeg2_scan_norm[64] ATTR_ALIGN(16) = +{ + /* Zig-Zag scan pattern */ + 0, 1, 8,16, 9, 2, 3,10, + 17,24,32,25,18,11, 4, 5, + 12,19,26,33,40,48,41,34, + 27,20,13, 6, 7,14,21,28, + 35,42,49,56,57,50,43,36, + 29,22,15,23,30,37,44,51, + 58,59,52,45,38,31,39,46, + 53,60,61,54,47,55,62,63 +}; + +uint8_t mpeg2_scan_alt[64] ATTR_ALIGN(16) = +{ + /* Alternate scan pattern */ + 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, + 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, + 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, + 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 +}; + +/* count must be between 1 and 32 */ +static uint32_t get_bits(uint8_t *buffer, uint32_t count, uint32_t *bit_position) { + uint32_t byte_offset; + uint32_t bit_offset; + uint32_t bit_mask; + uint32_t bit_bite; + uint32_t result=0; + if (count == 0) return 0; + do { + byte_offset = *bit_position >> 3; /* Div 8 */ + bit_offset = 8 - (*bit_position & 0x7); /* Bits got 87654321 */ + bit_mask = ((1 << (bit_offset)) - 1); + bit_bite = bit_offset; + if (count < bit_offset) { + bit_mask ^= ((1 << (bit_offset-count)) - 1); + bit_bite = count; + } + /* + printf("Byte=0x%02x Bitmask=0x%04x byte_offset=%u bit_offset=%u bit_byte=%u count=%u\n",buffer[byte_offset], bit_mask, byte_offset, bit_offset, bit_bite,count); + */ + result = (result << bit_bite) | ((buffer[byte_offset] & bit_mask) >> (bit_offset-bit_bite)); + *bit_position+=bit_bite; + count-=bit_bite; + } while ((count > 0) && (byte_offset<50) ); + return result; +} + +void mpeg2_header_state_init (picture_t * picture) +{ + picture->scan = mpeg2_scan_norm; + picture->load_intra_quantizer_matrix = 1; + picture->load_non_intra_quantizer_matrix = 1; +} + +int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer) +{ + int width, height; + int i; + + if ((buffer[6] & 0x20) != 0x20) + return 1; /* missing marker_bit */ + + height = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; + + picture->display_width = width = (height >> 12); + picture->display_height = height = (height & 0xfff); + + width = (width + 15) & ~15; + height = (height + 15) & ~15; + + if ((width > 1920) || (height > 1152)) + return 1; /* size restrictions for MP@HL */ + + picture->coded_picture_width = width; + picture->coded_picture_height = height; + + /* this is not used by the decoder */ + picture->aspect_ratio_information = buffer[3] >> 4; + picture->frame_rate_code = buffer[3] & 15; + picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6); + + if (buffer[7] & 2) { + for (i = 0; i < 64; i++) + picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = + (buffer[i+7] << 7) | (buffer[i+8] >> 1); + buffer += 64; + } else + for (i = 0; i < 64; i++) + picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = + default_intra_quantizer_matrix [i]; + + if (buffer[7] & 1) + for (i = 0; i < 64; i++) + picture->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = + buffer[i+8]; + else + for (i = 0; i < 64; i++) + picture->non_intra_quantizer_matrix[i] = 16; + picture->load_intra_quantizer_matrix = 1; + picture->load_non_intra_quantizer_matrix = 1; + /* MPEG1 - for testing only */ + picture->mpeg1 = 1; + picture->intra_dc_precision = 0; + picture->frame_pred_frame_dct = 1; + picture->q_scale_type = 0; + picture->concealment_motion_vectors = 0; + /* picture->alternate_scan = 0; */ + picture->picture_structure = FRAME_PICTURE; + /* picture->second_field = 0; */ + + return 0; +} + +static int sequence_extension (picture_t * picture, uint8_t * buffer) +{ + /* check chroma format, size extensions, marker bit */ + if (((buffer[1] & 0x07) != 0x02) || (buffer[2] & 0xe0) || + ((buffer[3] & 0x01) != 0x01)) + return 1; + + /* this is not used by the decoder */ + picture->progressive_sequence = (buffer[1] >> 3) & 1; + + picture->low_delay = buffer[5] & 0x80; + + if (!picture->progressive_sequence) + picture->coded_picture_height = + (picture->coded_picture_height + 31) & ~31; + + + /* printf ("libmpeg2: low_delay : %d\n", picture->low_delay); */ + +/* + printf ("libmpeg2: sequence extension+5 : %08x (%d)\n", + buffer[5], buffer[5] % 0x80); + */ + + picture->frame_rate_ext_n = buffer[5] & 0x31; + picture->frame_rate_ext_d = (buffer[5] >> 2) & 0x03; + + /* MPEG1 - for testing only */ + picture->mpeg1 = 0; + + return 0; +} + +static int quant_matrix_extension (picture_t * picture, uint8_t * buffer) +{ + int i; + + if (buffer[0] & 8) { + for (i = 0; i < 64; i++) + picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = + (buffer[i] << 5) | (buffer[i+1] >> 3); + buffer += 64; + } + + if (buffer[0] & 4) + for (i = 0; i < 64; i++) + picture->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = + (buffer[i] << 6) | (buffer[i+1] >> 2); + + return 0; +} + +static int picture_coding_extension (picture_t * picture, uint8_t * buffer) +{ + /* pre subtract 1 for use later in compute_motion_vector */ + picture->f_motion.f_code[0] = (buffer[0] & 15) - 1; + picture->f_motion.f_code[1] = (buffer[1] >> 4) - 1; + picture->b_motion.f_code[0] = (buffer[1] & 15) - 1; + picture->b_motion.f_code[1] = (buffer[2] >> 4) - 1; + + picture->intra_dc_precision = (buffer[2] >> 2) & 3; + picture->picture_structure = buffer[2] & 3; + picture->frame_pred_frame_dct = (buffer[3] >> 6) & 1; + picture->concealment_motion_vectors = (buffer[3] >> 5) & 1; + picture->q_scale_type = (buffer[3] >> 4) & 1; + picture->intra_vlc_format = (buffer[3] >> 3) & 1; + + if (buffer[3] & 4) /* alternate_scan */ + picture->scan = mpeg2_scan_alt; + else + picture->scan = mpeg2_scan_norm; + + /* these are not used by the decoder */ + picture->top_field_first = buffer[3] >> 7; + picture->repeat_first_field = (buffer[3] >> 1) & 1; + picture->progressive_frame = buffer[4] >> 7; + + return 0; +} + +static int sequence_display_extension (picture_t * picture, uint8_t * buffer) { + /* FIXME: implement. */ + uint32_t bit_position; + uint32_t padding; + + bit_position = 0; + padding = get_bits(buffer, 4, &bit_position); + picture->video_format = get_bits(buffer, 3, &bit_position); + picture->colour_description = get_bits(buffer, 1, &bit_position); + if(picture->colour_description) { + picture->colour_primatives = get_bits(buffer, 8, &bit_position); + picture->transfer_characteristics = get_bits(buffer, 8, &bit_position); + picture->matrix_coefficients = get_bits(buffer, 8, &bit_position); + } + picture->display_horizontal_size = get_bits(buffer, 14, &bit_position); + padding = get_bits(buffer, 1, &bit_position); + picture->display_vertical_size = get_bits(buffer, 14, &bit_position); + +#ifdef LOG_PAN_SCAN + printf("Sequence_display_extension\n"); + printf(" video_format: %u\n", picture->video_format); + printf(" colour_description: %u\n", picture->colour_description); + if(picture->colour_description) { + printf(" colour_primatives: %u\n", picture->colour_primatives); + printf(" transfer_characteristics %u\n", picture->transfer_characteristics); + printf(" matrix_coefficients %u\n", picture->matrix_coefficients); + } + printf(" display_horizontal_size %u\n", picture->display_horizontal_size); + printf(" display_vertical_size %u\n", picture->display_vertical_size); +#endif + + return 0; +} + +static int picture_display_extension (picture_t * picture, uint8_t * buffer) { + uint32_t bit_position; + uint32_t padding; + +#ifdef LOG_PAN_SCAN + printf ("libmpeg2: picture_display_extension\n"); +#endif + + bit_position = 0; + padding = get_bits(buffer, 4, &bit_position); + picture->frame_centre_horizontal_offset = get_bits(buffer, 16, &bit_position); + padding = get_bits(buffer, 1, &bit_position); + picture->frame_centre_vertical_offset = get_bits(buffer, 16, &bit_position); + padding = get_bits(buffer, 1, &bit_position); + +#ifdef LOG_PAN_SCAN + printf("Pan & Scan centre (x,y) = (%u, %u)\n", + picture->frame_centre_horizontal_offset, + picture->frame_centre_vertical_offset); +#endif + + return 0; +} + +int mpeg2_header_extension (picture_t * picture, uint8_t * buffer) +{ + switch (buffer[0] & 0xf0) { + case 0x00: /* reserved */ + return 0; + + case 0x10: /* sequence extension */ + return sequence_extension (picture, buffer); + + case 0x20: /* sequence display extension for Pan & Scan */ + return sequence_display_extension (picture, buffer); + + case 0x30: /* quant matrix extension */ + return quant_matrix_extension (picture, buffer); + + case 0x40: /* copyright extension */ + return 0; + + case 0x50: /* sequence scalable extension */ + return 0; + + case 0x60: /* reserved */ + return 0; + + case 0x70: /* picture display extension for Pan & Scan */ + return picture_display_extension (picture, buffer); + + case 0x80: /* picture coding extension */ + return picture_coding_extension (picture, buffer); + + case 0x90: /* picture spacial scalable extension */ + return 0; + + case 0xA0: /* picture temporal scalable extension */ + return 0; + + case 0xB0: /* camera parameters extension */ + return 0; + + case 0xC0: /* ITU-T extension */ + return 0; + + case 0xD0: /* reserved */ + return 0; + + case 0xE0: /* reserved */ + return 0; + + case 0xF0: /* reserved */ + return 0; + } + + return 0; +} + +int mpeg2_header_group_of_pictures (picture_t * picture, uint8_t * buffer) { + uint32_t bit_position; + uint32_t padding; + bit_position = 0; + + picture->drop_frame_flag = get_bits(buffer, 1, &bit_position); + picture->time_code_hours = get_bits(buffer, 5, &bit_position); + picture->time_code_minutes = get_bits(buffer, 6, &bit_position); + padding = get_bits(buffer, 1, &bit_position); + picture->time_code_seconds = get_bits(buffer, 6, &bit_position); + picture->time_code_pictures = get_bits(buffer, 6, &bit_position); + picture->closed_gop = get_bits(buffer, 1, &bit_position); + picture->broken_link = get_bits(buffer, 1, &bit_position); + +#ifdef LOG_PAN_SCAN + printf("Group of pictures\n"); + printf(" drop_frame_flag: %u\n", picture->drop_frame_flag); + printf(" time_code: HH:MM:SS:Pictures %02u:%02u:%02u:%02u\n", + picture->time_code_hours, + picture->time_code_minutes, + picture->time_code_seconds, + picture->time_code_pictures); + printf(" closed_gop: %u\n", picture->closed_gop); + printf(" bloken_link: %u\n", picture->broken_link); +#endif + + return 0; +} + +int mpeg2_header_picture (picture_t * picture, uint8_t * buffer) +{ + picture->picture_coding_type = (buffer [1] >> 3) & 7; + picture->vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) | + (buffer[3] >> 3)) & 0xffff; + + /* forward_f_code and backward_f_code - used in mpeg1 only */ + picture->f_motion.f_code[1] = (buffer[3] >> 2) & 1; + picture->f_motion.f_code[0] = + (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; + picture->b_motion.f_code[1] = (buffer[4] >> 6) & 1; + picture->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; + + /* move in header_process_picture_header */ + picture->second_field = + (picture->picture_structure != FRAME_PICTURE) && + !(picture->second_field); + + return 0; +} diff --git a/src/video_dec/libmpeg2/idct.c b/src/video_dec/libmpeg2/idct.c new file mode 100644 index 000000000..9f216db58 --- /dev/null +++ b/src/video_dec/libmpeg2/idct.c @@ -0,0 +1,348 @@ +/* + * idct.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * Portions of this code are from the MPEG software simulation group + * idct implementation. This code will be replaced with a new + * implementation soon. + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/**********************************************************/ +/* inverse two dimensional DCT, Chen-Wang algorithm */ +/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ +/* 32-bit integer arithmetic (8 bit coefficients) */ +/* 11 mults, 29 adds per DCT */ +/* sE, 18.8.91 */ +/**********************************************************/ +/* coefficients extended to 12 bit for IEEE1180-1990 */ +/* compliance sE, 2.1.94 */ +/**********************************************************/ + +/* this code assumes >> to be a two's-complement arithmetic */ +/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ + +#include "config.h" + +#include +#include +#include + +#include "mpeg2_internal.h" +#include + +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +/* idct main entry points */ +void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); +void (* mpeg2_idct_add) (int16_t * block, uint8_t * dest, int stride); +void (* mpeg2_idct) (int16_t * block); +void (* mpeg2_zero_block) (int16_t * block); + +static uint8_t clip_lut[1024]; +#define CLIP(i) ((clip_lut+384)[ (i)]) + +/* row (horizontal) IDCT + * + * 7 pi 1 + * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 128 + * c[1..7] = 128*sqrt (2) + */ + +static void inline idct_row (int16_t * block) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + x1 = block[4] << 11; + x2 = block[6]; + x3 = block[2]; + x4 = block[1]; + x5 = block[7]; + x6 = block[5]; + x7 = block[3]; + + /* shortcut */ + if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { + block[0] = block[1] = block[2] = block[3] = block[4] = + block[5] = block[6] = block[7] = block[0]<<3; + return; + } + + x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */ + + /* first stage */ + x8 = W7 * (x4 + x5); + x4 = x8 + (W1 - W7) * x4; + x5 = x8 - (W1 + W7) * x5; + x8 = W3 * (x6 + x7); + x6 = x8 - (W3 - W5) * x6; + x7 = x8 - (W3 + W5) * x7; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6 * (x3 + x2); + x2 = x1 - (W2 + W6) * x2; + x3 = x1 + (W2 - W6) * x3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + block[0] = (x7 + x1) >> 8; + block[1] = (x3 + x2) >> 8; + block[2] = (x0 + x4) >> 8; + block[3] = (x8 + x6) >> 8; + block[4] = (x8 - x6) >> 8; + block[5] = (x0 - x4) >> 8; + block[6] = (x3 - x2) >> 8; + block[7] = (x7 - x1) >> 8; +} + +/* column (vertical) IDCT + * + * 7 pi 1 + * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 1/1024 + * c[1..7] = (1/1024)*sqrt (2) + */ + +static void inline idct_col (int16_t *block) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + x1 = block [8*4] << 8; + x2 = block [8*6]; + x3 = block [8*2]; + x4 = block [8*1]; + x5 = block [8*7]; + x6 = block [8*5]; + x7 = block [8*3]; + +#if 0 + if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { + block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] = + block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6; + return; + } +#endif + + x0 = (block[8*0] << 8) + 8192; + + /* first stage */ + x8 = W7 * (x4 + x5) + 4; + x4 = (x8 + (W1 - W7) * x4) >> 3; + x5 = (x8 - (W1 + W7) * x5) >> 3; + x8 = W3 * (x6 + x7) + 4; + x6 = (x8 - (W3 - W5) * x6) >> 3; + x7 = (x8 - (W3 + W5) * x7) >> 3; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6 * (x3 + x2) + 4; + x2 = (x1 - (W2 + W6) * x2) >> 3; + x3 = (x1 + (W2 - W6) * x3) >> 3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + block[8*0] = (x7 + x1) >> 14; + block[8*1] = (x3 + x2) >> 14; + block[8*2] = (x0 + x4) >> 14; + block[8*3] = (x8 + x6) >> 14; + block[8*4] = (x8 - x6) >> 14; + block[8*5] = (x0 - x4) >> 14; + block[8*6] = (x3 - x2) >> 14; + block[8*7] = (x7 - x1) >> 14; +} + +static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest, int stride) +{ + int i; + + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + + for (i = 0; i < 8; i++) + idct_col (block + i); + + i = 8; + do { + dest[0] = CLIP (block[0]); + dest[1] = CLIP (block[1]); + dest[2] = CLIP (block[2]); + dest[3] = CLIP (block[3]); + dest[4] = CLIP (block[4]); + dest[5] = CLIP (block[5]); + dest[6] = CLIP (block[6]); + dest[7] = CLIP (block[7]); + + block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; + block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; + + dest += stride; + block += 8; + } while (--i); +} + +static void mpeg2_idct_add_c (int16_t * block, uint8_t * dest, int stride) +{ + int i; + + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + + for (i = 0; i < 8; i++) + idct_col (block + i); + + i = 8; + do { + dest[0] = CLIP (block[0] + dest[0]); + dest[1] = CLIP (block[1] + dest[1]); + dest[2] = CLIP (block[2] + dest[2]); + dest[3] = CLIP (block[3] + dest[3]); + dest[4] = CLIP (block[4] + dest[4]); + dest[5] = CLIP (block[5] + dest[5]); + dest[6] = CLIP (block[6] + dest[6]); + dest[7] = CLIP (block[7] + dest[7]); + + block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; + block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; + + dest += stride; + block += 8; + } while (--i); +} + +static void mpeg2_idct_c (int16_t * block) +{ + int i; + + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + + for (i = 0; i < 8; i++) + idct_col (block + i); +} + +static void mpeg2_zero_block_c (int16_t * wblock) +{ + memset( wblock, 0, sizeof(int16_t) * 64 ); +} + +void mpeg2_idct_init (uint32_t mm_accel) +{ + mpeg2_zero_block = mpeg2_zero_block_c; + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + if (mm_accel & MM_ACCEL_X86_MMXEXT) { +#ifdef LOG + fprintf (stderr, "Using MMXEXT for IDCT transform\n"); +#endif + mpeg2_idct_copy = mpeg2_idct_copy_mmxext; + mpeg2_idct_add = mpeg2_idct_add_mmxext; + mpeg2_idct = mpeg2_idct_mmxext; + mpeg2_zero_block = mpeg2_zero_block_mmx; + mpeg2_idct_mmx_init (); + } else if (mm_accel & MM_ACCEL_X86_MMX) { +#ifdef LOG + fprintf (stderr, "Using MMX for IDCT transform\n"); +#endif + mpeg2_idct_copy = mpeg2_idct_copy_mmx; + mpeg2_idct_add = mpeg2_idct_add_mmx; + mpeg2_idct = mpeg2_idct_mmx; + mpeg2_zero_block = mpeg2_zero_block_mmx; + mpeg2_idct_mmx_init (); + } else +#endif +#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) + if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { +#ifdef LOG + fprintf (stderr, "Using altivec for IDCT transform\n"); +#endif + mpeg2_idct_copy = mpeg2_idct_copy_altivec; + mpeg2_idct_add = mpeg2_idct_add_altivec; + mpeg2_idct_altivec_init (); + mpeg2_idct = mpeg2_idct_c; + } else +#endif +#ifdef LIBMPEG2_MLIB + if (mm_accel & MM_ACCEL_MLIB) { + char * env_var; + + env_var = getenv ("MLIB_NON_IEEE"); + + mpeg2_idct = mpeg2_idct_mlib; + if (env_var == NULL) { +#ifdef LOG + fprintf (stderr, "Using mlib for IDCT transform\n"); +#endif + mpeg2_idct_add = mpeg2_idct_add_mlib; + } else { + fprintf (stderr, "Using non-IEEE mlib for IDCT transform\n"); + mpeg2_idct_add = mpeg2_idct_add_mlib_non_ieee; + } + mpeg2_idct_copy = mpeg2_idct_copy_mlib_non_ieee; + } else +#endif + { + int i; + +#ifdef LOG + fprintf (stderr, "No accelerated IDCT transform found\n"); +#endif + mpeg2_idct_copy = mpeg2_idct_copy_c; + mpeg2_idct_add = mpeg2_idct_add_c; + mpeg2_idct = mpeg2_idct_c; + for (i = -384; i < 640; i++) + clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i); + } +} diff --git a/src/video_dec/libmpeg2/idct_altivec.c b/src/video_dec/libmpeg2/idct_altivec.c new file mode 100644 index 000000000..de396560b --- /dev/null +++ b/src/video_dec/libmpeg2/idct_altivec.c @@ -0,0 +1,233 @@ +/* + * idct_altivec.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) + +#include + +#include + +#include "mpeg2_internal.h" +#include + +#define vector_s16_t vector signed short +#define vector_u16_t vector unsigned short +#define vector_s8_t vector signed char +#define vector_u8_t vector unsigned char +#define vector_s32_t vector signed int +#define vector_u32_t vector unsigned int + +#define IDCT_HALF \ + /* 1st stage */ \ + t1 = vec_mradds (a1, vx7, vx1 ); \ + t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7)); \ + t7 = vec_mradds (a2, vx5, vx3); \ + t3 = vec_mradds (ma2, vx3, vx5); \ + \ + /* 2nd stage */ \ + t5 = vec_adds (vx0, vx4); \ + t0 = vec_subs (vx0, vx4); \ + t2 = vec_mradds (a0, vx6, vx2); \ + t4 = vec_mradds (a0, vx2, vec_subs (zero,vx6)); \ + t6 = vec_adds (t8, t3); \ + t3 = vec_subs (t8, t3); \ + t8 = vec_subs (t1, t7); \ + t1 = vec_adds (t1, t7); \ + \ + /* 3rd stage */ \ + t7 = vec_adds (t5, t2); \ + t2 = vec_subs (t5, t2); \ + t5 = vec_adds (t0, t4); \ + t0 = vec_subs (t0, t4); \ + t4 = vec_subs (t8, t3); \ + t3 = vec_adds (t8, t3); \ + \ + /* 4th stage */ \ + vy0 = vec_adds (t7, t1); \ + vy7 = vec_subs (t7, t1); \ + vy1 = vec_mradds (c4, t3, t5); \ + vy6 = vec_mradds (mc4, t3, t5); \ + vy2 = vec_mradds (c4, t4, t0); \ + vy5 = vec_mradds (mc4, t4, t0); \ + vy3 = vec_adds (t2, t6); \ + vy4 = vec_subs (t2, t6); + +#define IDCT \ + vector_s16_t vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7; \ + vector_s16_t vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7; \ + vector_s16_t a0, a1, a2, ma2, c4, mc4, zero, bias; \ + vector_s16_t t0, t1, t2, t3, t4, t5, t6, t7, t8; \ + vector_u16_t shift; \ + \ + c4 = vec_splat (constants[0], 0); \ + a0 = vec_splat (constants[0], 1); \ + a1 = vec_splat (constants[0], 2); \ + a2 = vec_splat (constants[0], 3); \ + mc4 = vec_splat (constants[0], 4); \ + ma2 = vec_splat (constants[0], 5); \ + bias = (vector_s16_t)vec_splat ((vector_s32_t)constants[0], 3); \ + \ + zero = vec_splat_s16 (0); \ + shift = vec_splat_u16 (4); \ + \ + vx0 = vec_mradds (vec_sl (block[0], shift), constants[1], zero); \ + vx1 = vec_mradds (vec_sl (block[1], shift), constants[2], zero); \ + vx2 = vec_mradds (vec_sl (block[2], shift), constants[3], zero); \ + vx3 = vec_mradds (vec_sl (block[3], shift), constants[4], zero); \ + vx4 = vec_mradds (vec_sl (block[4], shift), constants[1], zero); \ + vx5 = vec_mradds (vec_sl (block[5], shift), constants[4], zero); \ + vx6 = vec_mradds (vec_sl (block[6], shift), constants[3], zero); \ + vx7 = vec_mradds (vec_sl (block[7], shift), constants[2], zero); \ + \ + IDCT_HALF \ + \ + vx0 = vec_mergeh (vy0, vy4); \ + vx1 = vec_mergel (vy0, vy4); \ + vx2 = vec_mergeh (vy1, vy5); \ + vx3 = vec_mergel (vy1, vy5); \ + vx4 = vec_mergeh (vy2, vy6); \ + vx5 = vec_mergel (vy2, vy6); \ + vx6 = vec_mergeh (vy3, vy7); \ + vx7 = vec_mergel (vy3, vy7); \ + \ + vy0 = vec_mergeh (vx0, vx4); \ + vy1 = vec_mergel (vx0, vx4); \ + vy2 = vec_mergeh (vx1, vx5); \ + vy3 = vec_mergel (vx1, vx5); \ + vy4 = vec_mergeh (vx2, vx6); \ + vy5 = vec_mergel (vx2, vx6); \ + vy6 = vec_mergeh (vx3, vx7); \ + vy7 = vec_mergel (vx3, vx7); \ + \ + vx0 = vec_adds (vec_mergeh (vy0, vy4), bias); \ + vx1 = vec_mergel (vy0, vy4); \ + vx2 = vec_mergeh (vy1, vy5); \ + vx3 = vec_mergel (vy1, vy5); \ + vx4 = vec_mergeh (vy2, vy6); \ + vx5 = vec_mergel (vy2, vy6); \ + vx6 = vec_mergeh (vy3, vy7); \ + vx7 = vec_mergel (vy3, vy7); \ + \ + IDCT_HALF \ + \ + shift = vec_splat_u16 (6); \ + vx0 = vec_sra (vy0, shift); \ + vx1 = vec_sra (vy1, shift); \ + vx2 = vec_sra (vy2, shift); \ + vx3 = vec_sra (vy3, shift); \ + vx4 = vec_sra (vy4, shift); \ + vx5 = vec_sra (vy5, shift); \ + vx6 = vec_sra (vy6, shift); \ + vx7 = vec_sra (vy7, shift); + +#if defined( __APPLE_CC__ ) && defined( __APPLE_ALTIVEC__ ) /* apple */ +#define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) (a, b, c, d, e, f, g, h) +#else /* gnu */ +#define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) {a, b, c, d, e, f, g, h} +#endif + +static vector_s16_t constants[5] = { + VEC_S16(23170, 13573, 6518, 21895, -23170, -21895, 32, 31), + VEC_S16(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725), + VEC_S16(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521), + VEC_S16(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692), + VEC_S16(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722) +}; + +void mpeg2_idct_copy_altivec (vector_s16_t * block, unsigned char * dest, + int stride) +{ + vector_u8_t tmp; + + IDCT + +#define COPY(dest,src) \ + tmp = vec_packsu (src, src); \ + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + + COPY (dest, vx0) dest += stride; + COPY (dest, vx1) dest += stride; + COPY (dest, vx2) dest += stride; + COPY (dest, vx3) dest += stride; + COPY (dest, vx4) dest += stride; + COPY (dest, vx5) dest += stride; + COPY (dest, vx6) dest += stride; + COPY (dest, vx7) + memset (block, 0, 64 * sizeof (signed short)); +} + +void mpeg2_idct_add_altivec (vector_s16_t * block, unsigned char * dest, + int stride) +{ + vector_u8_t tmp; + vector_s16_t tmp2, tmp3; + vector_u8_t perm0; + vector_u8_t perm1; + vector_u8_t p0, p1, p; + + IDCT + + p0 = vec_lvsl (0, dest); + p1 = vec_lvsl (stride, dest); + p = vec_splat_u8 (-1); + perm0 = vec_mergeh (p, p0); + perm1 = vec_mergeh (p, p1); + +#define ADD(dest,src,perm) \ + /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ + tmp = vec_ld (0, dest); \ + tmp2 = (vector_s16_t)vec_perm (tmp, (vector_u8_t)zero, perm); \ + tmp3 = vec_adds (tmp2, src); \ + tmp = vec_packsu (tmp3, tmp3); \ + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + + ADD (dest, vx0, perm0) dest += stride; + ADD (dest, vx1, perm1) dest += stride; + ADD (dest, vx2, perm0) dest += stride; + ADD (dest, vx3, perm1) dest += stride; + ADD (dest, vx4, perm0) dest += stride; + ADD (dest, vx5, perm1) dest += stride; + ADD (dest, vx6, perm0) dest += stride; + ADD (dest, vx7, perm1) + memset (block, 0, 64 * sizeof (signed short)); +} + +void mpeg2_idct_altivec_init (void) +{ + int i, j; + + /* the altivec idct uses a transposed input, so we patch scan tables */ + for (i = 0; i < 64; i++) { + j = mpeg2_scan_norm[i]; + mpeg2_scan_norm[i] = (j >> 3) | ((j & 7) << 3); + j = mpeg2_scan_alt[i]; + mpeg2_scan_alt[i] = (j >> 3) | ((j & 7) << 3); + } +} + +#endif /* ARCH_PPC && ENABLED_ALTIVEC */ + diff --git a/src/video_dec/libmpeg2/idct_mlib.c b/src/video_dec/libmpeg2/idct_mlib.c new file mode 100644 index 000000000..e573c9790 --- /dev/null +++ b/src/video_dec/libmpeg2/idct_mlib.c @@ -0,0 +1,62 @@ +/* + * idct_mlib.c + * Copyright (C) 1999-2002 Håkan Hjort + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBMPEG2_MLIB + +#include +#include +#include +#include +#include +#include + +#include "mpeg2_internal.h" + +void mpeg2_idct_add_mlib (int16_t * block, uint8_t * dest, int stride) +{ + mlib_VideoIDCT_IEEE_S16_S16 (block, block); + mlib_VideoAddBlock_U8_S16 (dest, block, stride); + memset (block, 0, 64 * sizeof (uint16_t)); +} + +void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, + int stride) +{ + mlib_VideoIDCT8x8_U8_S16 (dest, block, stride); + memset (block, 0, 64 * sizeof (uint16_t)); +} + +void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, int stride) +{ + mlib_VideoIDCT8x8_S16_S16 (block, block); + mlib_VideoAddBlock_U8_S16 (dest, block, stride); + memset (block, 0, 64 * sizeof (uint16_t)); +} + +void mpeg2_idct_mlib (int16_t * block) +{ + mlib_VideoIDCT_IEEE_S16_S16 (block, block); +} + +#endif diff --git a/src/video_dec/libmpeg2/idct_mlib.h b/src/video_dec/libmpeg2/idct_mlib.h new file mode 100644 index 000000000..1fb0787dd --- /dev/null +++ b/src/video_dec/libmpeg2/idct_mlib.h @@ -0,0 +1,25 @@ +/* + * idct_mlib.h + * + * Copyright (C) 1999, Håkan Hjort + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec 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, or (at your option) + * any later version. + * + * mpeg2dec 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, + * + */ + +void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride); +void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride); diff --git a/src/video_dec/libmpeg2/idct_mmx.c b/src/video_dec/libmpeg2/idct_mmx.c new file mode 100644 index 000000000..6bb4bfbf0 --- /dev/null +++ b/src/video_dec/libmpeg2/idct_mmx.c @@ -0,0 +1,740 @@ +/* + * idct_mmx.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + +#include + +#include "mpeg2_internal.h" +#include + +#define ROW_SHIFT 11 +#define COL_SHIFT 6 + +#define round(bias) ((int)(((bias)+0.5) * (1<> ROW_SHIFT; + row[1] = (a1 + b1) >> ROW_SHIFT; + row[2] = (a2 + b2) >> ROW_SHIFT; + row[3] = (a3 + b3) >> ROW_SHIFT; + row[4] = (a3 - b3) >> ROW_SHIFT; + row[5] = (a2 - b2) >> ROW_SHIFT; + row[6] = (a1 - b1) >> ROW_SHIFT; + row[7] = (a0 - b0) >> ROW_SHIFT; +} +#endif + + +/* MMXEXT row IDCT */ + +#define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \ + c4, c6, c4, c6, \ + c1, c3, -c1, -c5, \ + c5, c7, c3, -c7, \ + c4, -c6, c4, -c6, \ + -c4, c2, c4, -c2, \ + c5, -c1, c3, -c1, \ + c7, c3, c7, -c5 } + +static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 + pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 + + pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 +} + +static inline void mmxext_row (int16_t * table, int32_t * rounder) +{ + movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1 + pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6 + + pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2 + pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5 + + movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5 + pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 + + paddd_m2r (*rounder, mm3); // mm3 += rounder + pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7 + + pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 + paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder + + pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3 + movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder + + pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7 + paddd_r2r (mm7, mm1); // mm1 = b1 b0 + + paddd_m2r (*rounder, mm0); // mm0 += rounder + psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder + + psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 + paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder + + paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder + psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 + + paddd_r2r (mm6, mm5); // mm5 = b3 b2 + movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder + + paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder + psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder +} + +static inline void mmxext_row_tail (int16_t * row, int store) +{ + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + + packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 + + /* slot */ + + movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 +} + +static inline void mmxext_row_mid (int16_t * row, int store, + int offset, int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 + + movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 + movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 + + pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 + + movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 + pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 +} + + +/* MMX row IDCT */ + +#define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \ + c4, c6, -c4, -c2, \ + c1, c3, c3, -c7, \ + c5, c7, -c1, -c5, \ + c4, -c6, c4, -c2, \ + -c4, c2, c4, -c6, \ + c5, -c1, c7, -c5, \ + c7, c3, c3, -c1 } + +static inline void mmx_row_head (int16_t * row, int offset, int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 + + movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 + pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 + + movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 + punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 +} + +static inline void mmx_row (int16_t * table, int32_t * rounder) +{ + pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 + punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1 + + pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2 + punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5 + + movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5 + pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3 + + paddd_m2r (*rounder, mm3); // mm3 += rounder + pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 + + pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 + paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder + + pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3 + movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder + + pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7 + paddd_r2r (mm7, mm1); // mm1 = b1 b0 + + paddd_m2r (*rounder, mm0); // mm0 += rounder + psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder + + psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 + paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder + + paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder + psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 + + paddd_r2r (mm6, mm5); // mm5 = b3 b2 + movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder + + paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder + psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder +} + +static inline void mmx_row_tail (int16_t * row, int store) +{ + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + + packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5 + + pslld_i2r (16, mm7); // mm7 = y7 0 y5 0 + + psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4 + + por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4 + + /* slot */ + + movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 +} + +static inline void mmx_row_mid (int16_t * row, int store, + int offset, int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5 + + punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 + psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4 + + movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 + pslld_i2r (16, mm1); // mm1 = y7 0 y5 0 + + movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 + por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4 + + movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 + punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 + + movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 + pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 +} + + +#if 0 +// C column IDCT - its just here to document the MMXEXT and MMX versions +static inline void idct_col (int16_t * col, int offset) +{ +/* multiplication - as implemented on mmx */ +#define F(c,x) (((c) * (x)) >> 16) + +/* saturation - it helps us handle torture test cases */ +#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x)) + + int16_t x0, x1, x2, x3, x4, x5, x6, x7; + int16_t y0, y1, y2, y3, y4, y5, y6, y7; + int16_t a0, a1, a2, a3, b0, b1, b2, b3; + int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12; + + col += offset; + + x0 = col[0*8]; + x1 = col[1*8]; + x2 = col[2*8]; + x3 = col[3*8]; + x4 = col[4*8]; + x5 = col[5*8]; + x6 = col[6*8]; + x7 = col[7*8]; + + u04 = S (x0 + x4); + v04 = S (x0 - x4); + u26 = S (F (T2, x6) + x2); + v26 = S (F (T2, x2) - x6); + + a0 = S (u04 + u26); + a1 = S (v04 + v26); + a2 = S (v04 - v26); + a3 = S (u04 - u26); + + u17 = S (F (T1, x7) + x1); + v17 = S (F (T1, x1) - x7); + u35 = S (F (T3, x5) + x3); + v35 = S (F (T3, x3) - x5); + + b0 = S (u17 + u35); + b3 = S (v17 - v35); + u12 = S (u17 - u35); + v12 = S (v17 + v35); + u12 = S (2 * F (C4, u12)); + v12 = S (2 * F (C4, v12)); + b1 = S (u12 + v12); + b2 = S (u12 - v12); + + y0 = S (a0 + b0) >> COL_SHIFT; + y1 = S (a1 + b1) >> COL_SHIFT; + y2 = S (a2 + b2) >> COL_SHIFT; + y3 = S (a3 + b3) >> COL_SHIFT; + + y4 = S (a3 - b3) >> COL_SHIFT; + y5 = S (a2 - b2) >> COL_SHIFT; + y6 = S (a1 - b1) >> COL_SHIFT; + y7 = S (a0 - b0) >> COL_SHIFT; + + col[0*8] = y0; + col[1*8] = y1; + col[2*8] = y2; + col[3*8] = y3; + col[4*8] = y4; + col[5*8] = y5; + col[6*8] = y6; + col[7*8] = y7; +} +#endif + + +// MMX column IDCT +static inline void idct_col (int16_t * col, int offset) +{ +#define T1 13036 +#define T2 27146 +#define T3 43790 +#define C4 23170 + + static short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; + static short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; + static short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; + static short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; + + /* column code adapted from peter gubanov */ + /* http://www.elecard.com/peter/idct.shtml */ + + movq_m2r (*_T1, mm0); // mm0 = T1 + + movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1 + movq_r2r (mm0, mm2); // mm2 = T1 + + movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7 + pmulhw_r2r (mm1, mm0); // mm0 = T1*x1 + + movq_m2r (*_T3, mm5); // mm5 = T3 + pmulhw_r2r (mm4, mm2); // mm2 = T1*x7 + + movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5 + movq_r2r (mm5, mm7); // mm7 = T3-1 + + movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3 + psubsw_r2r (mm4, mm0); // mm0 = v17 + + movq_m2r (*_T2, mm4); // mm4 = T2 + pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3 + + paddsw_r2r (mm2, mm1); // mm1 = u17 + pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5 + + /* slot */ + + movq_r2r (mm4, mm2); // mm2 = T2 + paddsw_r2r (mm3, mm5); // mm5 = T3*x3 + + pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2 + paddsw_r2r (mm6, mm7); // mm7 = T3*x5 + + psubsw_r2r (mm6, mm5); // mm5 = v35 + paddsw_r2r (mm3, mm7); // mm7 = u35 + + movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6 + movq_r2r (mm0, mm6); // mm6 = v17 + + pmulhw_r2r (mm3, mm2); // mm2 = T2*x6 + psubsw_r2r (mm5, mm0); // mm0 = b3 + + psubsw_r2r (mm3, mm4); // mm4 = v26 + paddsw_r2r (mm6, mm5); // mm5 = v12 + + movq_r2m (mm0, *(col+offset+3*8)); // save b3 in scratch0 + movq_r2r (mm1, mm6); // mm6 = u17 + + paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26 + paddsw_r2r (mm7, mm6); // mm6 = b0 + + psubsw_r2r (mm7, mm1); // mm1 = u12 + movq_r2r (mm1, mm7); // mm7 = u12 + + movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0 + paddsw_r2r (mm5, mm1); // mm1 = u12+v12 + + movq_m2r (*_C4, mm0); // mm0 = C4/2 + psubsw_r2r (mm5, mm7); // mm7 = u12-v12 + + movq_r2m (mm6, *(col+offset+5*8)); // save b0 in scratch1 + pmulhw_r2r (mm0, mm1); // mm1 = b1/2 + + movq_r2r (mm4, mm6); // mm6 = v26 + pmulhw_r2r (mm0, mm7); // mm7 = b2/2 + + movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4 + movq_r2r (mm3, mm0); // mm0 = x0 + + psubsw_r2r (mm5, mm3); // mm3 = v04 + paddsw_r2r (mm5, mm0); // mm0 = u04 + + paddsw_r2r (mm3, mm4); // mm4 = a1 + movq_r2r (mm0, mm5); // mm5 = u04 + + psubsw_r2r (mm6, mm3); // mm3 = a2 + paddsw_r2r (mm2, mm5); // mm5 = a0 + + paddsw_r2r (mm1, mm1); // mm1 = b1 + psubsw_r2r (mm2, mm0); // mm0 = a3 + + paddsw_r2r (mm7, mm7); // mm7 = b2 + movq_r2r (mm3, mm2); // mm2 = a2 + + movq_r2r (mm4, mm6); // mm6 = a1 + paddsw_r2r (mm7, mm3); // mm3 = a2+b2 + + psraw_i2r (COL_SHIFT, mm3); // mm3 = y2 + paddsw_r2r (mm1, mm4); // mm4 = a1+b1 + + psraw_i2r (COL_SHIFT, mm4); // mm4 = y1 + psubsw_r2r (mm1, mm6); // mm6 = a1-b1 + + movq_m2r (*(col+offset+5*8), mm1); // mm1 = b0 + psubsw_r2r (mm7, mm2); // mm2 = a2-b2 + + psraw_i2r (COL_SHIFT, mm6); // mm6 = y6 + movq_r2r (mm5, mm7); // mm7 = a0 + + movq_r2m (mm4, *(col+offset+1*8)); // save y1 + psraw_i2r (COL_SHIFT, mm2); // mm2 = y5 + + movq_r2m (mm3, *(col+offset+2*8)); // save y2 + paddsw_r2r (mm1, mm5); // mm5 = a0+b0 + + movq_m2r (*(col+offset+3*8), mm4); // mm4 = b3 + psubsw_r2r (mm1, mm7); // mm7 = a0-b0 + + psraw_i2r (COL_SHIFT, mm5); // mm5 = y0 + movq_r2r (mm0, mm3); // mm3 = a3 + + movq_r2m (mm2, *(col+offset+5*8)); // save y5 + psubsw_r2r (mm4, mm3); // mm3 = a3-b3 + + psraw_i2r (COL_SHIFT, mm7); // mm7 = y7 + paddsw_r2r (mm0, mm4); // mm4 = a3+b3 + + movq_r2m (mm5, *(col+offset+0*8)); // save y0 + psraw_i2r (COL_SHIFT, mm3); // mm3 = y4 + + movq_r2m (mm6, *(col+offset+6*8)); // save y6 + psraw_i2r (COL_SHIFT, mm4); // mm4 = y3 + + movq_r2m (mm7, *(col+offset+7*8)); // save y7 + + movq_r2m (mm3, *(col+offset+4*8)); // save y4 + + movq_r2m (mm4, *(col+offset+3*8)); // save y3 +} + + +static int32_t rounder0[] ATTR_ALIGN(8) = + rounder ((1 << (COL_SHIFT - 1)) - 0.5); +static int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); +static int32_t rounder1[] ATTR_ALIGN(8) = + rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ +static int32_t rounder7[] ATTR_ALIGN(8) = + rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ +static int32_t rounder2[] ATTR_ALIGN(8) = + rounder (0.60355339059); /* C2 * (C6+C2)/2 */ +static int32_t rounder6[] ATTR_ALIGN(8) = + rounder (-0.25); /* C2 * (C6-C2)/2 */ +static int32_t rounder3[] ATTR_ALIGN(8) = + rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ +static int32_t rounder5[] ATTR_ALIGN(8) = + rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ + + +#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ +static inline void idct (int16_t * block) \ +{ \ + static int16_t table04[] ATTR_ALIGN(16) = \ + table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ + static int16_t table17[] ATTR_ALIGN(16) = \ + table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ + static int16_t table26[] ATTR_ALIGN(16) = \ + table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ + static int16_t table35[] ATTR_ALIGN(16) = \ + table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ + \ + idct_row_head (block, 0*8, table04); \ + idct_row (table04, rounder0); \ + idct_row_mid (block, 0*8, 4*8, table04); \ + idct_row (table04, rounder4); \ + idct_row_mid (block, 4*8, 1*8, table17); \ + idct_row (table17, rounder1); \ + idct_row_mid (block, 1*8, 7*8, table17); \ + idct_row (table17, rounder7); \ + idct_row_mid (block, 7*8, 2*8, table26); \ + idct_row (table26, rounder2); \ + idct_row_mid (block, 2*8, 6*8, table26); \ + idct_row (table26, rounder6); \ + idct_row_mid (block, 6*8, 3*8, table35); \ + idct_row (table35, rounder3); \ + idct_row_mid (block, 3*8, 5*8, table35); \ + idct_row (table35, rounder5); \ + idct_row_tail (block, 5*8); \ + \ + idct_col (block, 0); \ + idct_col (block, 4); \ +} + + +#define COPY_MMX(offset,r0,r1,r2) \ +do { \ + movq_m2r (*(block+offset), r0); \ + dest += stride; \ + movq_m2r (*(block+offset+4), r1); \ + movq_r2m (r2, *dest); \ + packuswb_r2r (r1, r0); \ +} while (0) + +static void block_copy (int16_t * block, uint8_t * dest, int stride) +{ + movq_m2r (*(block+0*8), mm0); + movq_m2r (*(block+0*8+4), mm1); + movq_m2r (*(block+1*8), mm2); + packuswb_r2r (mm1, mm0); + movq_m2r (*(block+1*8+4), mm3); + movq_r2m (mm0, *dest); + packuswb_r2r (mm3, mm2); + COPY_MMX (2*8, mm0, mm1, mm2); + COPY_MMX (3*8, mm2, mm3, mm0); + COPY_MMX (4*8, mm0, mm1, mm2); + COPY_MMX (5*8, mm2, mm3, mm0); + COPY_MMX (6*8, mm0, mm1, mm2); + COPY_MMX (7*8, mm2, mm3, mm0); + movq_r2m (mm2, *(dest+stride)); +} + + +#define ADD_MMX(offset,r1,r2,r3,r4) \ +do { \ + movq_m2r (*(dest+2*stride), r1); \ + packuswb_r2r (r4, r3); \ + movq_r2r (r1, r2); \ + dest += stride; \ + movq_r2m (r3, *dest); \ + punpcklbw_r2r (mm0, r1); \ + paddsw_m2r (*(block+offset), r1); \ + punpckhbw_r2r (mm0, r2); \ + paddsw_m2r (*(block+offset+4), r2); \ +} while (0) + +static void block_add (int16_t * block, uint8_t * dest, int stride) +{ + movq_m2r (*dest, mm1); + pxor_r2r (mm0, mm0); + movq_m2r (*(dest+stride), mm3); + movq_r2r (mm1, mm2); + punpcklbw_r2r (mm0, mm1); + movq_r2r (mm3, mm4); + paddsw_m2r (*(block+0*8), mm1); + punpckhbw_r2r (mm0, mm2); + paddsw_m2r (*(block+0*8+4), mm2); + punpcklbw_r2r (mm0, mm3); + paddsw_m2r (*(block+1*8), mm3); + packuswb_r2r (mm2, mm1); + punpckhbw_r2r (mm0, mm4); + movq_r2m (mm1, *dest); + paddsw_m2r (*(block+1*8+4), mm4); + ADD_MMX (2*8, mm1, mm2, mm3, mm4); + ADD_MMX (3*8, mm3, mm4, mm1, mm2); + ADD_MMX (4*8, mm1, mm2, mm3, mm4); + ADD_MMX (5*8, mm3, mm4, mm1, mm2); + ADD_MMX (6*8, mm1, mm2, mm3, mm4); + ADD_MMX (7*8, mm3, mm4, mm1, mm2); + packuswb_r2r (mm4, mm3); + movq_r2m (mm3, *(dest+stride)); +} + +static inline void block_zero (int16_t * block) { + pxor_r2r (mm0, mm0); + movq_r2m (mm0, *(block+0*4)); + movq_r2m (mm0, *(block+1*4)); + movq_r2m (mm0, *(block+2*4)); + movq_r2m (mm0, *(block+3*4)); + movq_r2m (mm0, *(block+4*4)); + movq_r2m (mm0, *(block+5*4)); + movq_r2m (mm0, *(block+6*4)); + movq_r2m (mm0, *(block+7*4)); + movq_r2m (mm0, *(block+8*4)); + movq_r2m (mm0, *(block+9*4)); + movq_r2m (mm0, *(block+10*4)); + movq_r2m (mm0, *(block+11*4)); + movq_r2m (mm0, *(block+12*4)); + movq_r2m (mm0, *(block+13*4)); + movq_r2m (mm0, *(block+14*4)); + movq_r2m (mm0, *(block+15*4)); +} + +declare_idct (mmxext_idct, mmxext_table, + mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid) + +void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride) +{ + mmxext_idct (block); + block_copy (block, dest, stride); + block_zero (block); +} + +void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int stride) +{ + mmxext_idct (block); + block_add (block, dest, stride); + block_zero (block); +} + +void mpeg2_idct_mmxext (int16_t * block) +{ + mmxext_idct (block); +} + +declare_idct (mmx_idct, mmx_table, + mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid) + +void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride) +{ + mmx_idct (block); + block_copy (block, dest, stride); + block_zero (block); +} + +void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int stride) +{ + mmx_idct (block); + block_add (block, dest, stride); + block_zero (block); +} + +void mpeg2_idct_mmx (int16_t * block) +{ + mmx_idct (block); +} + +void mpeg2_zero_block_mmx (int16_t * block) +{ + block_zero (block); +} + +void mpeg2_idct_mmx_init (void) +{ + int i, j; + + /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ + + for (i = 0; i < 64; i++) { + j = mpeg2_scan_norm[i]; + mpeg2_scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); + j = mpeg2_scan_alt[i]; + mpeg2_scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); + } +} + +#endif diff --git a/src/video_dec/libmpeg2/libmpeg2_accel.c b/src/video_dec/libmpeg2/libmpeg2_accel.c new file mode 100644 index 000000000..92c0e280b --- /dev/null +++ b/src/video_dec/libmpeg2/libmpeg2_accel.c @@ -0,0 +1,223 @@ +/* + * libmpeg2_accel.c + * Copyright (C) 2004 The Unichrome Project. + * Copyright (C) 2005 Thomas Hellstrom. + * + * 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 + */ + +#include +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "xvmc_vld.h" +#include "libmpeg2_accel.h" + + +void +libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt) +{ + xvmc_setup_scan_ptable(); +} + + +int +libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture) +{ + accel->xvmc_last_slice_code=-1; + if ( !picture->current_frame ) + return 0; + if (frame_format == XINE_IMGFMT_XXMC) { + xine_xxmc_t *xxmc = (xine_xxmc_t *) + picture->current_frame->accel_data; + switch(xxmc->acceleration) { + case XINE_XVMC_ACCEL_VLD: + case XINE_XVMC_ACCEL_IDCT: + case XINE_XVMC_ACCEL_MOCOMP: + xxmc->proc_xxmc_flush( picture->current_frame ); + break; + default: + break; + } + } + return 0; +} + +int +libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture) +{ + switch(frame_format) { + case XINE_IMGFMT_XXMC: + case XINE_IMGFMT_XVMC: { + xine_xvmc_t *xvmc = (xine_xvmc_t *) + picture->current_frame->accel_data; + picture->mc = xvmc->macroblocks; + return 0; + } + default: + break; + } + return 1; +} + +int +libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, + picture_t *picture, double ratio, uint32_t flags) +{ + if (picture->current_frame) { + if (XINE_IMGFMT_XXMC == frame_format) { + xine_xxmc_t *xxmc = (xine_xxmc_t *) + picture->current_frame->accel_data; + + /* + * Make a request for acceleration type and mpeg coding from + * the output plugin. + */ + + xxmc->fallback_format = XINE_IMGFMT_YV12; + xxmc->acceleration = XINE_XVMC_ACCEL_VLD| XINE_XVMC_ACCEL_IDCT + | XINE_XVMC_ACCEL_MOCOMP ; + + /* + * Standard MOCOMP / IDCT XvMC implementation for interlaced streams + * is buggy. The bug is inherited from the old XvMC driver. Don't use it until + * it has been fixed. (A volunteer ?) + */ + + if ( picture->picture_structure != 3 ) { + picture->top_field_first = (picture->picture_structure == 1); + xxmc->acceleration &= ~( XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP ); + } + + xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2; + xxmc->proc_xxmc_update_frame (picture->current_frame->driver, + picture->current_frame, + picture->coded_picture_width, + picture->coded_picture_height, + ratio, + XINE_IMGFMT_XXMC, flags); + } + } + return 0; +} + +void +libmpeg2_accel_frame_completion(mpeg2dec_accel_t * accel, uint32_t frame_format, picture_t *picture, + int code) +{ + + if ( !picture->current_frame ) return; + + if (frame_format == XINE_IMGFMT_XXMC) { + xine_xxmc_t *xxmc = (xine_xxmc_t *) + picture->current_frame->accel_data; + if (!xxmc->decoded) { + switch(picture->current_frame->format) { + case XINE_IMGFMT_XXMC: + switch(xxmc->acceleration) { + case XINE_XVMC_ACCEL_VLD: + mpeg2_xxmc_vld_frame_complete(accel, picture, code); + break; + case XINE_XVMC_ACCEL_IDCT: + case XINE_XVMC_ACCEL_MOCOMP: + xxmc->decoded = !picture->current_frame->bad_frame; + xxmc->proc_xxmc_flush( picture->current_frame ); + break; + default: + break; + } + default: + break; + } + } + } +} + + +int +libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, char * buffer, + uint32_t chunk_size, uint8_t *chunk_buffer) +{ + /* + * Don't reference frames of other formats. They are invalid. This may happen if the + * xxmc plugin suddenly falls back to software decoding. + */ + + if (( picture->current_frame->picture_coding_type == XINE_PICT_P_TYPE ) || + ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE )) { + if (! picture->forward_reference_frame) return 1; + if (picture->forward_reference_frame->format != picture->current_frame->format) { + picture->v_offset = 0; + return 1; + } + } + + if ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE ) { + if (! picture->backward_reference_frame) return 1; + if (picture->backward_reference_frame->format != picture->current_frame->format) { + picture->v_offset = 0; + return 1; + } + } + + switch( picture->current_frame->format ) { + + case XINE_IMGFMT_XXMC: + { + xine_xxmc_t *xxmc = (xine_xxmc_t *) + picture->current_frame->accel_data; + + if ( xxmc->proc_xxmc_lock_valid( picture->current_frame, + picture->forward_reference_frame, + picture->backward_reference_frame, + picture->current_frame->picture_coding_type)) { + picture->v_offset = 0; + return 1; + } + + switch(picture->current_frame->format) { + case XINE_IMGFMT_XXMC: + switch(xxmc->acceleration) { + case XINE_XVMC_ACCEL_VLD: + mpeg2_xxmc_slice(accel, picture, code, buffer, chunk_size, chunk_buffer); + break; + case XINE_XVMC_ACCEL_IDCT: + case XINE_XVMC_ACCEL_MOCOMP: + mpeg2_xvmc_slice (accel, picture, code, buffer); + break; + default: + mpeg2_slice (picture, code, buffer); + break; + } + break; + default: + mpeg2_slice (picture, code, buffer); + break; + } + xxmc->proc_xxmc_unlock(picture->current_frame->driver); + break; + } + + case XINE_IMGFMT_XVMC: + mpeg2_xvmc_slice (accel, picture, code, buffer); + break; + + default: + mpeg2_slice (picture, code, buffer); + break; + } + return 0; +} diff --git a/src/video_dec/libmpeg2/libmpeg2_accel.h b/src/video_dec/libmpeg2/libmpeg2_accel.h new file mode 100644 index 000000000..5d0b37a78 --- /dev/null +++ b/src/video_dec/libmpeg2/libmpeg2_accel.h @@ -0,0 +1,48 @@ +/* + * libmpeg2_accel.h + * Copyright (C) 2004 The Unichrome Project. + * Copyright (C) 2005 Thomas Hellstrom. + * + * 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 + */ + +#ifndef LIBMPEG2_ACCEL_H +#define LIBMPEG2_ACCEL_H + +#include "mpeg2_internal.h" + +/* + * Internal context data type. + */ + +typedef struct { + int xvmc_last_slice_code; + int slices_per_row; + int row_slice_count; + unsigned xxmc_mb_pic_height; +} mpeg2dec_accel_t; + +extern int libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture); +extern int libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture); +extern int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, double ratio, uint32_t flags); +extern void libmpeg2_accel_frame_completion(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, int code); + +extern int libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, + char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer); +extern void libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt); + +#endif diff --git a/src/video_dec/libmpeg2/motion_comp.c b/src/video_dec/libmpeg2/motion_comp.c new file mode 100644 index 000000000..9328dfb9f --- /dev/null +++ b/src/video_dec/libmpeg2/motion_comp.c @@ -0,0 +1,154 @@ +/* + * motion_comp.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "mpeg2_internal.h" +#include + +mpeg2_mc_t mpeg2_mc; + +void mpeg2_mc_init (uint32_t mm_accel) +{ +#ifdef LIBMPEG2_MLIB + if (mm_accel & MM_ACCEL_MLIB) { +#ifdef LOG + fprintf (stderr, "Using mediaLib for motion compensation\n"); +#endif + mpeg2_mc = mpeg2_mc_mlib; + } +#endif + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + if (mm_accel & MM_ACCEL_X86_MMXEXT) { +#ifdef LOG + fprintf (stderr, "Using MMXEXT for motion compensation\n"); +#endif + mpeg2_mc = mpeg2_mc_mmxext; + } else if (mm_accel & MM_ACCEL_X86_3DNOW) { +#ifdef LOG + fprintf (stderr, "Using 3DNOW for motion compensation\n"); +#endif + mpeg2_mc = mpeg2_mc_3dnow; + } else if (mm_accel & MM_ACCEL_X86_MMX) { +#ifdef LOG + fprintf (stderr, "Using MMX for motion compensation\n"); +#endif + mpeg2_mc = mpeg2_mc_mmx; + } else +#endif +#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) + if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { +#ifdef LOG + fprintf (stderr, "Using altivec for motion compensation\n"); +#endif + mpeg2_mc = mpeg2_mc_altivec; + } else +#endif +#ifdef ARCH_SPARC + if (mm_accel & MM_ACCEL_SPARC_VIS) { +#ifdef LOG + fprintf (stderr, "Using VIS for motion compensation\n"); +#endif + mpeg2_mc = mpeg2_mc_vis; + } else +#endif + { +#ifdef LOG + fprintf (stderr, "No accelerated motion compensation found\n"); +#endif + mpeg2_mc = mpeg2_mc_c; + } +} + +#define avg2(a,b) ((a+b+1)>>1) +#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) + +#define predict_o(i) (ref[i]) +#define predict_x(i) (avg2 (ref[i], ref[i+1])) +#define predict_y(i) (avg2 (ref[i], (ref+stride)[i])) +#define predict_xy(i) (avg4 (ref[i], ref[i+1], \ + (ref+stride)[i], (ref+stride)[i+1])) + +#define put(predictor,i) dest[i] = predictor (i) +#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i]) + +/* mc function template */ + +#define MC_FUNC(op,xy) \ +static void MC_##op##_##xy##_16_c (uint8_t * dest, uint8_t * ref, \ + int stride, int height) \ +{ \ + do { \ + op (predict_##xy, 0); \ + op (predict_##xy, 1); \ + op (predict_##xy, 2); \ + op (predict_##xy, 3); \ + op (predict_##xy, 4); \ + op (predict_##xy, 5); \ + op (predict_##xy, 6); \ + op (predict_##xy, 7); \ + op (predict_##xy, 8); \ + op (predict_##xy, 9); \ + op (predict_##xy, 10); \ + op (predict_##xy, 11); \ + op (predict_##xy, 12); \ + op (predict_##xy, 13); \ + op (predict_##xy, 14); \ + op (predict_##xy, 15); \ + ref += stride; \ + dest += stride; \ + } while (--height); \ +} \ +static void MC_##op##_##xy##_8_c (uint8_t * dest, uint8_t * ref, \ + int stride, int height) \ +{ \ + do { \ + op (predict_##xy, 0); \ + op (predict_##xy, 1); \ + op (predict_##xy, 2); \ + op (predict_##xy, 3); \ + op (predict_##xy, 4); \ + op (predict_##xy, 5); \ + op (predict_##xy, 6); \ + op (predict_##xy, 7); \ + ref += stride; \ + dest += stride; \ + } while (--height); \ +} + +/* definitions of the actual mc functions */ + +MC_FUNC (put,o) +MC_FUNC (avg,o) +MC_FUNC (put,x) +MC_FUNC (avg,x) +MC_FUNC (put,y) +MC_FUNC (avg,y) +MC_FUNC (put,xy) +MC_FUNC (avg,xy) + +MPEG2_MC_EXTERN (c) diff --git a/src/video_dec/libmpeg2/motion_comp_altivec.c b/src/video_dec/libmpeg2/motion_comp_altivec.c new file mode 100644 index 000000000..99719b7fb --- /dev/null +++ b/src/video_dec/libmpeg2/motion_comp_altivec.c @@ -0,0 +1,2031 @@ +/* + * motion_comp_altivec.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifndef HOST_OS_DARWIN + +#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) + +#include "mpeg2_internal.h" + +#include + +/* + * The asm code is generated with: + * + * gcc-2.95 -fvec -DHOST_OS_DARWIN -O9 -fomit-frame-pointer -mregnames -S + * motion_comp_altivec.c + * + * sed 's/.L/._L/g' motion_comp_altivec.s | + * awk '{args=""; len=split ($2, arg, ","); + * for (i=1; i<=len; i++) { a=arg[i]; if (i> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp = vec_perm (ref0, ref1, perm); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, 0, dest); + tmp = vec_perm (ref0, ref1, perm); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_perm (ref0, ref1, perm); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + vec_st (tmp, 0, dest); + tmp = vec_perm (ref0, ref1, perm); + vec_st (tmp, stride, dest); +} + +void MC_put_o_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_put_x_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, tmp; + + permA = vec_lvsl (0, ref); + permB = vec_add (permA, vec_splat_u8 (1)); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, 0, dest); + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + vec_st (tmp, 0, dest); + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + vec_st (tmp, stride, dest); +} + +void MC_put_x_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; + + ones = vec_splat_u8 (1); + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + perm0B = vec_add (perm0A, ones); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B)); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_put_y_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp; + + perm = vec_lvsl (0, ref); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + vec_st (tmp, stride, dest); +} + +void MC_put_y_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (tmp0, tmp1); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (tmp0, tmp1); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (tmp0, tmp1); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (tmp0, tmp1); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +void MC_put_xy_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; + vector_u8_t ones; + + ones = vec_splat_u8 (1); + permA = vec_lvsl (0, ref); + permB = vec_add (permA, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + vec_st (tmp, stride, dest); +} + +void MC_put_xy_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; + vector_u8_t avg0, avg1, xor0, xor1, tmp, ones; + + ones = vec_splat_u8 (1); + perm0A = vec_lvsl (0, ref); + perm0A = vec_mergeh (perm0A, perm0A); + perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); + perm0B = vec_add (perm0A, ones); + perm1A = vec_lvsl (stride, ref); + perm1A = vec_mergeh (perm1A, perm1A); + perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +#if 0 +void MC_put_xy_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, A, B, C, D, tmp, zero, ones; + vector_u16_t splat2, temp; + + ones = vec_splat_u8 (1); + permA = vec_lvsl (0, ref); + permB = vec_add (permA, ones); + + zero = vec_splat_u8 (0); + splat2 = vec_splat_u16 (2); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + C = vec_perm (ref0, ref1, permA); + D = vec_perm (ref0, ref1, permB); + + temp = vec_add (vec_add ((vector_u16_t)vec_mergeh (zero, A), + (vector_u16_t)vec_mergeh (zero, B)), + vec_add ((vector_u16_t)vec_mergeh (zero, C), + (vector_u16_t)vec_mergeh (zero, D))); + temp = vec_sr (vec_add (temp, splat2), splat2); + tmp = vec_pack (temp, temp); + + vec_st (tmp, 0, dest); + dest += stride; + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + } while (--height); +} +#endif + +void MC_avg_o_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm, ref0, ref1, tmp, prev; + + perm = vec_lvsl (0, ref); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + vec_st (tmp, stride, dest); +} + +void MC_avg_o_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1, prev; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_avg_x_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, tmp, prev; + + permA = vec_lvsl (0, ref); + permB = vec_add (permA, vec_splat_u8 (1)); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (0, dest); + ref += stride; + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + vec_st (tmp, stride, dest); +} + +void MC_avg_x_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; + vector_u8_t prev; + + ones = vec_splat_u8 (1); + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + perm0B = vec_add (perm0A, ones); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + prev = vec_ld (0, dest); + ref += stride; + tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B))); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_avg_y_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp, prev; + + perm = vec_lvsl (0, ref); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + vec_st (tmp, stride, dest); +} + +void MC_avg_y_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1, prev; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +void MC_avg_xy_16_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; + vector_u8_t ones, prev; + + ones = vec_splat_u8 (1); + permA = vec_lvsl (0, ref); + permB = vec_add (permA, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + vec_st (tmp, stride, dest); +} + +void MC_avg_xy_8_altivec (unsigned char * dest, unsigned char * ref, + int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; + vector_u8_t avg0, avg1, xor0, xor1, tmp, ones, prev; + + ones = vec_splat_u8 (1); + perm0A = vec_lvsl (0, ref); + perm0A = vec_mergeh (perm0A, perm0A); + perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); + perm0B = vec_add (perm0A, ones); + perm1A = vec_lvsl (stride, ref); + perm1A = vec_mergeh (perm1A, perm1A); + perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (0, dest); + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +MPEG2_MC_EXTERN (altivec) + +#endif /* ENABLE_ALTIVEC */ + +#endif /* HOST_OS_DARWIN */ + diff --git a/src/video_dec/libmpeg2/motion_comp_mlib.c b/src/video_dec/libmpeg2/motion_comp_mlib.c new file mode 100644 index 000000000..1a37070ae --- /dev/null +++ b/src/video_dec/libmpeg2/motion_comp_mlib.c @@ -0,0 +1,181 @@ +/* + * motion_comp_mlib.c + * Copyright (C) 2000-2002 Håkan Hjort + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBMPEG2_MLIB + +#include +#include +#include +#include +#include + +#include "mpeg2_internal.h" + +static void MC_put_o_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoCopyRef_U8_U8_16x16 (dest, ref, stride); + else + mlib_VideoCopyRef_U8_U8_16x8 (dest, ref, stride); +} + +static void MC_put_x_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpX_U8_U8_16x16 (dest, ref, stride, stride); + else + mlib_VideoInterpX_U8_U8_16x8 (dest, ref, stride, stride); +} + +static void MC_put_y_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpY_U8_U8_16x16 (dest, ref, stride, stride); + else + mlib_VideoInterpY_U8_U8_16x8 (dest, ref, stride, stride); +} + +static void MC_put_xy_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpXY_U8_U8_16x16 (dest, ref, stride, stride); + else + mlib_VideoInterpXY_U8_U8_16x8 (dest, ref, stride, stride); +} + +static void MC_put_o_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoCopyRef_U8_U8_8x8 (dest, ref, stride); + else + mlib_VideoCopyRef_U8_U8_8x4 (dest, ref, stride); +} + +static void MC_put_x_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpX_U8_U8_8x8 (dest, ref, stride, stride); + else + mlib_VideoInterpX_U8_U8_8x4 (dest, ref, stride, stride); +} + +static void MC_put_y_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpY_U8_U8_8x8 (dest, ref, stride, stride); + else + mlib_VideoInterpY_U8_U8_8x4 (dest, ref, stride, stride); +} + +static void MC_put_xy_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpXY_U8_U8_8x8 (dest, ref, stride, stride); + else + mlib_VideoInterpXY_U8_U8_8x4 (dest, ref, stride, stride); +} + +static void MC_avg_o_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoCopyRefAve_U8_U8_16x16 (dest, ref, stride); + else + mlib_VideoCopyRefAve_U8_U8_16x8 (dest, ref, stride); +} + +static void MC_avg_x_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpAveX_U8_U8_16x16 (dest, ref, stride, stride); + else + mlib_VideoInterpAveX_U8_U8_16x8 (dest, ref, stride, stride); +} + +static void MC_avg_y_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpAveY_U8_U8_16x16 (dest, ref, stride, stride); + else + mlib_VideoInterpAveY_U8_U8_16x8 (dest, ref, stride, stride); +} + +static void MC_avg_xy_16_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpAveXY_U8_U8_16x16 (dest, ref, stride, stride); + else + mlib_VideoInterpAveXY_U8_U8_16x8 (dest, ref, stride, stride); +} + +static void MC_avg_o_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoCopyRefAve_U8_U8_8x8 (dest, ref, stride); + else + mlib_VideoCopyRefAve_U8_U8_8x4 (dest, ref, stride); +} + +static void MC_avg_x_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpAveX_U8_U8_8x8 (dest, ref, stride, stride); + else + mlib_VideoInterpAveX_U8_U8_8x4 (dest, ref, stride, stride); +} + +static void MC_avg_y_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpAveY_U8_U8_8x8 (dest, ref, stride, stride); + else + mlib_VideoInterpAveY_U8_U8_8x4 (dest, ref, stride, stride); +} + +static void MC_avg_xy_8_mlib (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpAveXY_U8_U8_8x8 (dest, ref, stride, stride); + else + mlib_VideoInterpAveXY_U8_U8_8x4 (dest, ref, stride, stride); +} + +MPEG2_MC_EXTERN (mlib) + +#endif diff --git a/src/video_dec/libmpeg2/motion_comp_mmx.c b/src/video_dec/libmpeg2/motion_comp_mmx.c new file mode 100644 index 000000000..f9b1f085d --- /dev/null +++ b/src/video_dec/libmpeg2/motion_comp_mmx.c @@ -0,0 +1,1012 @@ +/* + * motion_comp_mmx.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + +#include + +#include "mpeg2_internal.h" +#include + +#define CPU_MMXEXT 0 +#define CPU_3DNOW 1 + + +/* MMX code - needs a rewrite */ + +/* some rounding constants */ +static mmx_t round1 = {0x0001000100010001LL}; +static mmx_t round4 = {0x0002000200020002LL}; + +/* + * This code should probably be compiled with loop unrolling + * (ie, -funroll-loops in gcc)becuase some of the loops + * use a small static number of iterations. This was written + * with the assumption the compiler knows best about when + * unrolling will help + */ + +static inline void mmx_zero_reg () +{ + /* load 0 into mm0 */ + pxor_r2r (mm0, mm0); +} + +static inline void mmx_average_2_U8 (uint8_t * dest, + uint8_t * src1, uint8_t * src2) +{ + /* *dest = (*src1 + *src2 + 1)/ 2; */ + + movq_m2r (*src1, mm1); // load 8 src1 bytes + movq_r2r (mm1, mm2); // copy 8 src1 bytes + + movq_m2r (*src2, mm3); // load 8 src2 bytes + movq_r2r (mm3, mm4); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes + + paddw_r2r (mm3, mm1); // add lows to mm1 + paddw_m2r (round1, mm1); + psraw_i2r (1, mm1); // /2 + + paddw_r2r (mm4, mm2); // add highs to mm2 + paddw_m2r (round1, mm2); + psraw_i2r (1, mm2); // /2 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1, *dest); // store result in dest +} + +static inline void mmx_interp_average_2_U8 (uint8_t * dest, + uint8_t * src1, uint8_t * src2) +{ + /* *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; */ + + movq_m2r (*dest, mm1); // load 8 dest bytes + movq_r2r (mm1, mm2); // copy 8 dest bytes + + movq_m2r (*src1, mm3); // load 8 src1 bytes + movq_r2r (mm3, mm4); // copy 8 src1 bytes + + movq_m2r (*src2, mm5); // load 8 src2 bytes + movq_r2r (mm5, mm6); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low dest bytes + punpckhbw_r2r (mm0, mm2); // unpack high dest bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src1 bytes + + punpcklbw_r2r (mm0, mm5); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm6); // unpack high src2 bytes + + paddw_r2r (mm5, mm3); // add lows + paddw_m2r (round1, mm3); + psraw_i2r (1, mm3); // /2 + + paddw_r2r (mm6, mm4); // add highs + paddw_m2r (round1, mm4); + psraw_i2r (1, mm4); // /2 + + paddw_r2r (mm3, mm1); // add lows + paddw_m2r (round1, mm1); + psraw_i2r (1, mm1); // /2 + + paddw_r2r (mm4, mm2); // add highs + paddw_m2r (round1, mm2); + psraw_i2r (1, mm2); // /2 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1, *dest); // store result in dest +} + +static inline void mmx_average_4_U8 (uint8_t * dest, + uint8_t * src1, uint8_t * src2, + uint8_t * src3, uint8_t * src4) +{ + /* *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; */ + + movq_m2r (*src1, mm1); // load 8 src1 bytes + movq_r2r (mm1, mm2); // copy 8 src1 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes + + movq_m2r (*src2, mm3); // load 8 src2 bytes + movq_r2r (mm3, mm4); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + /* now have partials in mm1 and mm2 */ + + movq_m2r (*src3, mm3); // load 8 src3 bytes + movq_r2r (mm3, mm4); // copy 8 src3 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + movq_m2r (*src4, mm5); // load 8 src4 bytes + movq_r2r (mm5, mm6); // copy 8 src4 bytes + + punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes + punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes + + paddw_r2r (mm5, mm1); // add lows + paddw_r2r (mm6, mm2); // add highs + + /* now have subtotal in mm1 and mm2 */ + + paddw_m2r (round4, mm1); + psraw_i2r (2, mm1); // /4 + paddw_m2r (round4, mm2); + psraw_i2r (2, mm2); // /4 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1, *dest); // store result in dest +} + +static inline void mmx_interp_average_4_U8 (uint8_t * dest, + uint8_t * src1, uint8_t * src2, + uint8_t * src3, uint8_t * src4) +{ + /* *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; */ + + movq_m2r (*src1, mm1); // load 8 src1 bytes + movq_r2r (mm1, mm2); // copy 8 src1 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes + + movq_m2r (*src2, mm3); // load 8 src2 bytes + movq_r2r (mm3, mm4); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + /* now have partials in mm1 and mm2 */ + + movq_m2r (*src3, mm3); // load 8 src3 bytes + movq_r2r (mm3, mm4); // copy 8 src3 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + movq_m2r (*src4, mm5); // load 8 src4 bytes + movq_r2r (mm5, mm6); // copy 8 src4 bytes + + punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes + punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes + + paddw_r2r (mm5, mm1); // add lows + paddw_r2r (mm6, mm2); // add highs + + paddw_m2r (round4, mm1); + psraw_i2r (2, mm1); // /4 + paddw_m2r (round4, mm2); + psraw_i2r (2, mm2); // /4 + + /* now have subtotal/4 in mm1 and mm2 */ + + movq_m2r (*dest, mm3); // load 8 dest bytes + movq_r2r (mm3, mm4); // copy 8 dest bytes + + punpcklbw_r2r (mm0, mm3); // unpack low dest bytes + punpckhbw_r2r (mm0, mm4); // unpack high dest bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + paddw_m2r (round1, mm1); + psraw_i2r (1, mm1); // /2 + paddw_m2r (round1, mm2); + psraw_i2r (1, mm2); // /2 + + /* now have end value in mm1 and mm2 */ + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1,*dest); // store result in dest +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_avg_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, dest, ref); + + if (width == 16) + mmx_average_2_U8 (dest+8, dest+8, ref+8); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_avg_o_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_o_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + movq_m2r (* ref, mm1); // load 8 ref bytes + movq_r2m (mm1,* dest); // store 8 bytes at curr + + if (width == 16) + { + movq_m2r (* (ref+8), mm1); // load 8 ref bytes + movq_r2m (mm1,* (dest+8)); // store 8 bytes at curr + } + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_put_o_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_mmx (16, height, dest, ref, stride); +} + +static void MC_put_o_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +/* Half pixel interpolation in the x direction */ +static inline void MC_avg_x_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + mmx_interp_average_2_U8 (dest, ref, ref+1); + + if (width == 16) + mmx_interp_average_2_U8 (dest+8, ref+8, ref+9); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_avg_x_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_x_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_x_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_x_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_x_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, ref, ref+1); + + if (width == 16) + mmx_average_2_U8 (dest+8, ref+8, ref+9); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_put_x_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_x_mmx (16, height, dest, ref, stride); +} + +static void MC_put_x_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_x_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_avg_xy_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + uint8_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); + + if (width == 16) + mmx_interp_average_4_U8 (dest+8, ref+8, ref+9, + ref_next+8, ref_next+9); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_avg_xy_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_xy_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_xy_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_xy_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_xy_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + uint8_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); + + if (width == 16) + mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_put_xy_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_xy_mmx (16, height, dest, ref, stride); +} + +static void MC_put_xy_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_xy_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_avg_y_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + uint8_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_interp_average_2_U8 (dest, ref, ref_next); + + if (width == 16) + mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_avg_y_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_y_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_y_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg_y_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_y_mmx (int width, int height, + uint8_t * dest, uint8_t * ref, int stride) +{ + uint8_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, ref, ref_next); + + if (width == 16) + mmx_average_2_U8 (dest+8, ref+8, ref_next+8); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_put_y_16_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_y_mmx (16, height, dest, ref, stride); +} + +static void MC_put_y_8_mmx (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put_y_mmx (8, height, dest, ref, stride); +} + + +MPEG2_MC_EXTERN (mmx) + + + + + + + +/* CPU_MMXEXT/CPU_3DNOW adaptation layer */ + +#define pavg_r2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_r2r (src, dest); \ + else \ + pavgusb_r2r (src, dest); \ +} while (0) + +#define pavg_m2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_m2r (src, dest); \ + else \ + pavgusb_m2r (src, dest); \ +} while (0) + + +/* CPU_MMXEXT code */ + + +static inline void MC_put1_8 (int height, uint8_t * dest, uint8_t * ref, + int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_r2m (mm0, *dest); + ref += stride; + dest += stride; + } while (--height); +} + +static inline void MC_put1_16 (int height, uint8_t * dest, uint8_t * ref, + int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_avg1_8 (int height, uint8_t * dest, uint8_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_avg1_16 (int height, uint8_t * dest, uint8_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_put2_8 (int height, uint8_t * dest, uint8_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_put2_16 (int height, uint8_t * dest, uint8_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_avg2_8 (int height, uint8_t * dest, uint8_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_avg2_16 (int height, uint8_t * dest, uint8_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static mmx_t mask_one = {0x0101010101010101LL}; + +static inline void MC_put4_8 (int height, uint8_t * dest, uint8_t * ref, + int stride, int cpu) +{ + movq_m2r (*ref, mm0); + movq_m2r (*(ref+1), mm1); + movq_r2r (mm0, mm7); + pxor_r2r (mm1, mm7); + pavg_r2r (mm1, mm0); + ref += stride; + + do { + movq_m2r (*ref, mm2); + movq_r2r (mm0, mm5); + + movq_m2r (*(ref+1), mm3); + movq_r2r (mm2, mm6); + + pxor_r2r (mm3, mm6); + pavg_r2r (mm3, mm2); + + por_r2r (mm6, mm7); + pxor_r2r (mm2, mm5); + + pand_r2r (mm5, mm7); + pavg_r2r (mm2, mm0); + + pand_m2r (mask_one, mm7); + + psubusb_r2r (mm7, mm0); + + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + + movq_r2r (mm6, mm7); // unroll ! + movq_r2r (mm2, mm0); // unroll ! + } while (--height); +} + +static inline void MC_put4_16 (int height, uint8_t * dest, uint8_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_avg4_8 (int height, uint8_t * dest, uint8_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_avg4_16 (int height, uint8_t * dest, uint8_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*(dest+8), mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static void MC_avg_o_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_o_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_o_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_o_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_x_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_y_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_y_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_xy_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_xy_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy_16_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy_8_mmxext (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + + +MPEG2_MC_EXTERN (mmxext) + + + +static void MC_avg_o_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_o_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_o_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_o_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_x_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_y_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_y_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_xy_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_xy_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy_16_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy_8_3dnow (uint8_t * dest, uint8_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); +} + + +MPEG2_MC_EXTERN (3dnow) + +#endif diff --git a/src/video_dec/libmpeg2/motion_comp_vis.c b/src/video_dec/libmpeg2/motion_comp_vis.c new file mode 100644 index 000000000..d0a6673d6 --- /dev/null +++ b/src/video_dec/libmpeg2/motion_comp_vis.c @@ -0,0 +1,2059 @@ +/* + * motion_comp_vis.c + * Copyright (C) 2003 David S. Miller + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#if defined(ARCH_SPARC) && defined(ENABLE_VIS) + +#include + +#include "mpeg2_internal.h" +#include "vis.h" + +/* The trick used in some of this file is the formula from the MMX + * motion comp code, which is: + * + * (x+y+1)>>1 == (x|y)-((x^y)>>1) + * + * This allows us to average 8 bytes at a time in a 64-bit FPU reg. + * We avoid overflows by masking before we do the shift, and we + * implement the shift by multiplying by 1/2 using mul8x16. So in + * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask + * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and + * the value 0x80808080 is in f8): + * + * fxor f0, f2, f10 + * fand f10, f4, f10 + * fmul8x16 f8, f10, f10 + * fand f10, f6, f10 + * for f0, f2, f12 + * fpsub16 f12, f10, f10 + */ + +#define DUP4(x) {x, x, x, x} +#define DUP8(x) {x, x, x, x, x, x, x, x} +static const int16_t constants1[] ATTR_ALIGN(8) = DUP4 (1); +static const int16_t constants2[] ATTR_ALIGN(8) = DUP4 (2); +static const int16_t constants3[] ATTR_ALIGN(8) = DUP4 (3); +static const int16_t constants6[] ATTR_ALIGN(8) = DUP4 (6); +static const int8_t constants_fe[] ATTR_ALIGN(8) = DUP8 (0xfe); +static const int8_t constants_7f[] ATTR_ALIGN(8) = DUP8 (0x7f); +static const int8_t constants128[] ATTR_ALIGN(8) = DUP8 (128); +static const int16_t constants256_512[] ATTR_ALIGN(8) = + {256, 512, 256, 512}; +static const int16_t constants256_1024[] ATTR_ALIGN(8) = + {256, 1024, 256, 1024}; + +#define REF_0 0 +#define REF_0_1 1 +#define REF_2 2 +#define REF_2_1 3 +#define REF_4 4 +#define REF_4_1 5 +#define REF_6 6 +#define REF_6_1 7 +#define REF_S0 8 +#define REF_S0_1 9 +#define REF_S2 10 +#define REF_S2_1 11 +#define REF_S4 12 +#define REF_S4_1 13 +#define REF_S6 14 +#define REF_S6_1 15 +#define DST_0 16 +#define DST_1 17 +#define DST_2 18 +#define DST_3 19 +#define CONST_1 20 +#define CONST_2 20 +#define CONST_3 20 +#define CONST_6 20 +#define MASK_fe 20 +#define CONST_128 22 +#define CONST_256 22 +#define CONST_512 22 +#define CONST_1024 22 +#define TMP0 24 +#define TMP1 25 +#define TMP2 26 +#define TMP3 27 +#define TMP4 28 +#define TMP5 29 +#define ZERO 30 +#define MASK_7f 30 + +#define TMP6 32 +#define TMP8 34 +#define TMP10 36 +#define TMP12 38 +#define TMP14 40 +#define TMP16 42 +#define TMP18 44 +#define TMP20 46 +#define TMP22 48 +#define TMP24 50 +#define TMP26 52 +#define TMP28 54 +#define TMP30 56 +#define TMP32 58 + +static void MC_put_o_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int offset; + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 16 : 0; + do { /* 5 cycles */ + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, 8, TMP2); + + vis_ld64_2(ref, offset, TMP4); + ref += stride; + + vis_faligndata(TMP0, TMP2, REF_0); + vis_st64(REF_0, dest[0]); + + vis_faligndata(TMP2, TMP4, REF_2); + vis_st64_2(REF_2, dest, 8); + dest += stride; + } while (--height); +} + +static void MC_put_o_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int offset; + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 8 : 0; + do { /* 4 cycles */ + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, offset, TMP2); + ref += stride; + + /* stall */ + + vis_faligndata(TMP0, TMP2, REF_0); + vis_st64(REF_0, dest[0]); + dest += stride; + } while (--height); +} + + +static void MC_avg_o_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int stride_8 = stride + 8; + int offset; + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 16 : 0; + + vis_ld64(ref[0], TMP0); + + vis_ld64(ref[8], TMP2); + + vis_ld64_2(ref, offset, TMP4); + + vis_ld64(dest[0], DST_0); + + vis_ld64(dest[8], DST_2); + + vis_ld64(constants_fe[0], MASK_fe); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64(constants_7f[0], MASK_7f); + vis_faligndata(TMP2, TMP4, REF_2); + + vis_ld64(constants128[0], CONST_128); + + ref += stride; + height = (height >> 1) - 1; + + do { /* 24 cycles */ + vis_ld64(ref[0], TMP0); + vis_xor(DST_0, REF_0, TMP6); + + vis_ld64_2(ref, 8, TMP2); + vis_and(TMP6, MASK_fe, TMP6); + + vis_ld64_2(ref, offset, TMP4); + ref += stride; + vis_mul8x16(CONST_128, TMP6, TMP6); + vis_xor(DST_2, REF_2, TMP8); + + vis_and(TMP8, MASK_fe, TMP8); + + vis_or(DST_0, REF_0, TMP10); + vis_ld64_2(dest, stride, DST_0); + vis_mul8x16(CONST_128, TMP8, TMP8); + + vis_or(DST_2, REF_2, TMP12); + vis_ld64_2(dest, stride_8, DST_2); + + vis_ld64(ref[0], TMP14); + vis_and(TMP6, MASK_7f, TMP6); + + vis_and(TMP8, MASK_7f, TMP8); + + vis_psub16(TMP10, TMP6, TMP6); + vis_st64(TMP6, dest[0]); + + vis_psub16(TMP12, TMP8, TMP8); + vis_st64_2(TMP8, dest, 8); + + dest += stride; + vis_ld64_2(ref, 8, TMP16); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, offset, TMP18); + vis_faligndata(TMP2, TMP4, REF_2); + ref += stride; + + vis_xor(DST_0, REF_0, TMP20); + + vis_and(TMP20, MASK_fe, TMP20); + + vis_xor(DST_2, REF_2, TMP22); + vis_mul8x16(CONST_128, TMP20, TMP20); + + vis_and(TMP22, MASK_fe, TMP22); + + vis_or(DST_0, REF_0, TMP24); + vis_mul8x16(CONST_128, TMP22, TMP22); + + vis_or(DST_2, REF_2, TMP26); + + vis_ld64_2(dest, stride, DST_0); + vis_faligndata(TMP14, TMP16, REF_0); + + vis_ld64_2(dest, stride_8, DST_2); + vis_faligndata(TMP16, TMP18, REF_2); + + vis_and(TMP20, MASK_7f, TMP20); + + vis_and(TMP22, MASK_7f, TMP22); + + vis_psub16(TMP24, TMP20, TMP20); + vis_st64(TMP20, dest[0]); + + vis_psub16(TMP26, TMP22, TMP22); + vis_st64_2(TMP22, dest, 8); + dest += stride; + } while (--height); + + vis_ld64(ref[0], TMP0); + vis_xor(DST_0, REF_0, TMP6); + + vis_ld64_2(ref, 8, TMP2); + vis_and(TMP6, MASK_fe, TMP6); + + vis_ld64_2(ref, offset, TMP4); + vis_mul8x16(CONST_128, TMP6, TMP6); + vis_xor(DST_2, REF_2, TMP8); + + vis_and(TMP8, MASK_fe, TMP8); + + vis_or(DST_0, REF_0, TMP10); + vis_ld64_2(dest, stride, DST_0); + vis_mul8x16(CONST_128, TMP8, TMP8); + + vis_or(DST_2, REF_2, TMP12); + vis_ld64_2(dest, stride_8, DST_2); + + vis_ld64(ref[0], TMP14); + vis_and(TMP6, MASK_7f, TMP6); + + vis_and(TMP8, MASK_7f, TMP8); + + vis_psub16(TMP10, TMP6, TMP6); + vis_st64(TMP6, dest[0]); + + vis_psub16(TMP12, TMP8, TMP8); + vis_st64_2(TMP8, dest, 8); + + dest += stride; + vis_faligndata(TMP0, TMP2, REF_0); + + vis_faligndata(TMP2, TMP4, REF_2); + + vis_xor(DST_0, REF_0, TMP20); + + vis_and(TMP20, MASK_fe, TMP20); + + vis_xor(DST_2, REF_2, TMP22); + vis_mul8x16(CONST_128, TMP20, TMP20); + + vis_and(TMP22, MASK_fe, TMP22); + + vis_or(DST_0, REF_0, TMP24); + vis_mul8x16(CONST_128, TMP22, TMP22); + + vis_or(DST_2, REF_2, TMP26); + + vis_and(TMP20, MASK_7f, TMP20); + + vis_and(TMP22, MASK_7f, TMP22); + + vis_psub16(TMP24, TMP20, TMP20); + vis_st64(TMP20, dest[0]); + + vis_psub16(TMP26, TMP22, TMP22); + vis_st64_2(TMP22, dest, 8); +} + +static void MC_avg_o_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int offset; + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 8 : 0; + + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, offset, TMP2); + + vis_ld64(dest[0], DST_0); + + vis_ld64(constants_fe[0], MASK_fe); + + vis_ld64(constants_7f[0], MASK_7f); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64(constants128[0], CONST_128); + + ref += stride; + height = (height >> 1) - 1; + + do { /* 12 cycles */ + vis_ld64(ref[0], TMP0); + vis_xor(DST_0, REF_0, TMP4); + + vis_ld64_2(ref, offset, TMP2); + vis_and(TMP4, MASK_fe, TMP4); + + vis_or(DST_0, REF_0, TMP6); + vis_ld64_2(dest, stride, DST_0); + ref += stride; + vis_mul8x16(CONST_128, TMP4, TMP4); + + vis_ld64(ref[0], TMP12); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, offset, TMP2); + vis_xor(DST_0, REF_0, TMP0); + ref += stride; + + vis_and(TMP0, MASK_fe, TMP0); + + vis_and(TMP4, MASK_7f, TMP4); + + vis_psub16(TMP6, TMP4, TMP4); + vis_st64(TMP4, dest[0]); + dest += stride; + vis_mul8x16(CONST_128, TMP0, TMP0); + + vis_or(DST_0, REF_0, TMP6); + vis_ld64_2(dest, stride, DST_0); + + vis_faligndata(TMP12, TMP2, REF_0); + + vis_and(TMP0, MASK_7f, TMP0); + + vis_psub16(TMP6, TMP0, TMP4); + vis_st64(TMP4, dest[0]); + dest += stride; + } while (--height); + + vis_ld64(ref[0], TMP0); + vis_xor(DST_0, REF_0, TMP4); + + vis_ld64_2(ref, offset, TMP2); + vis_and(TMP4, MASK_fe, TMP4); + + vis_or(DST_0, REF_0, TMP6); + vis_ld64_2(dest, stride, DST_0); + vis_mul8x16(CONST_128, TMP4, TMP4); + + vis_faligndata(TMP0, TMP2, REF_0); + + vis_xor(DST_0, REF_0, TMP0); + + vis_and(TMP0, MASK_fe, TMP0); + + vis_and(TMP4, MASK_7f, TMP4); + + vis_psub16(TMP6, TMP4, TMP4); + vis_st64(TMP4, dest[0]); + dest += stride; + vis_mul8x16(CONST_128, TMP0, TMP0); + + vis_or(DST_0, REF_0, TMP6); + + vis_and(TMP0, MASK_7f, TMP0); + + vis_psub16(TMP6, TMP0, TMP4); + vis_st64(TMP4, dest[0]); +} + +static void MC_put_x_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + + ref = vis_alignaddr(ref); + + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, 8, TMP2); + + vis_ld64_2(ref, 16, TMP4); + + vis_ld64(constants_fe[0], MASK_fe); + + vis_ld64(constants_7f[0], MASK_7f); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64(constants128[0], CONST_128); + vis_faligndata(TMP2, TMP4, REF_4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + vis_faligndata(TMP2, TMP4, REF_6); + } else { + vis_src1(TMP2, REF_2); + vis_src1(TMP4, REF_6); + } + + ref += stride; + height = (height >> 1) - 1; + + do { /* 34 cycles */ + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP6); + + vis_ld64_2(ref, 8, TMP2); + vis_xor(REF_4, REF_6, TMP8); + + vis_ld64_2(ref, 16, TMP4); + vis_and(TMP6, MASK_fe, TMP6); + ref += stride; + + vis_ld64(ref[0], TMP14); + vis_mul8x16(CONST_128, TMP6, TMP6); + vis_and(TMP8, MASK_fe, TMP8); + + vis_ld64_2(ref, 8, TMP16); + vis_mul8x16(CONST_128, TMP8, TMP8); + vis_or(REF_0, REF_2, TMP10); + + vis_ld64_2(ref, 16, TMP18); + ref += stride; + vis_or(REF_4, REF_6, TMP12); + + vis_alignaddr_g0((void *)off); + + vis_faligndata(TMP0, TMP2, REF_0); + + vis_faligndata(TMP2, TMP4, REF_4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + vis_faligndata(TMP2, TMP4, REF_6); + } else { + vis_src1(TMP2, REF_2); + vis_src1(TMP4, REF_6); + } + + vis_and(TMP6, MASK_7f, TMP6); + + vis_and(TMP8, MASK_7f, TMP8); + + vis_psub16(TMP10, TMP6, TMP6); + vis_st64(TMP6, dest[0]); + + vis_psub16(TMP12, TMP8, TMP8); + vis_st64_2(TMP8, dest, 8); + dest += stride; + + vis_xor(REF_0, REF_2, TMP6); + + vis_xor(REF_4, REF_6, TMP8); + + vis_and(TMP6, MASK_fe, TMP6); + + vis_mul8x16(CONST_128, TMP6, TMP6); + vis_and(TMP8, MASK_fe, TMP8); + + vis_mul8x16(CONST_128, TMP8, TMP8); + vis_or(REF_0, REF_2, TMP10); + + vis_or(REF_4, REF_6, TMP12); + + vis_alignaddr_g0((void *)off); + + vis_faligndata(TMP14, TMP16, REF_0); + + vis_faligndata(TMP16, TMP18, REF_4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP14, TMP16, REF_2); + vis_faligndata(TMP16, TMP18, REF_6); + } else { + vis_src1(TMP16, REF_2); + vis_src1(TMP18, REF_6); + } + + vis_and(TMP6, MASK_7f, TMP6); + + vis_and(TMP8, MASK_7f, TMP8); + + vis_psub16(TMP10, TMP6, TMP6); + vis_st64(TMP6, dest[0]); + + vis_psub16(TMP12, TMP8, TMP8); + vis_st64_2(TMP8, dest, 8); + dest += stride; + } while (--height); + + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP6); + + vis_ld64_2(ref, 8, TMP2); + vis_xor(REF_4, REF_6, TMP8); + + vis_ld64_2(ref, 16, TMP4); + vis_and(TMP6, MASK_fe, TMP6); + + vis_mul8x16(CONST_128, TMP6, TMP6); + vis_and(TMP8, MASK_fe, TMP8); + + vis_mul8x16(CONST_128, TMP8, TMP8); + vis_or(REF_0, REF_2, TMP10); + + vis_or(REF_4, REF_6, TMP12); + + vis_alignaddr_g0((void *)off); + + vis_faligndata(TMP0, TMP2, REF_0); + + vis_faligndata(TMP2, TMP4, REF_4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + vis_faligndata(TMP2, TMP4, REF_6); + } else { + vis_src1(TMP2, REF_2); + vis_src1(TMP4, REF_6); + } + + vis_and(TMP6, MASK_7f, TMP6); + + vis_and(TMP8, MASK_7f, TMP8); + + vis_psub16(TMP10, TMP6, TMP6); + vis_st64(TMP6, dest[0]); + + vis_psub16(TMP12, TMP8, TMP8); + vis_st64_2(TMP8, dest, 8); + dest += stride; + + vis_xor(REF_0, REF_2, TMP6); + + vis_xor(REF_4, REF_6, TMP8); + + vis_and(TMP6, MASK_fe, TMP6); + + vis_mul8x16(CONST_128, TMP6, TMP6); + vis_and(TMP8, MASK_fe, TMP8); + + vis_mul8x16(CONST_128, TMP8, TMP8); + vis_or(REF_0, REF_2, TMP10); + + vis_or(REF_4, REF_6, TMP12); + + vis_and(TMP6, MASK_7f, TMP6); + + vis_and(TMP8, MASK_7f, TMP8); + + vis_psub16(TMP10, TMP6, TMP6); + vis_st64(TMP6, dest[0]); + + vis_psub16(TMP12, TMP8, TMP8); + vis_st64_2(TMP8, dest, 8); +} + +static void MC_put_x_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + + ref = vis_alignaddr(ref); + + vis_ld64(ref[0], TMP0); + + vis_ld64(ref[8], TMP2); + + vis_ld64(constants_fe[0], MASK_fe); + + vis_ld64(constants_7f[0], MASK_7f); + + vis_ld64(constants128[0], CONST_128); + vis_faligndata(TMP0, TMP2, REF_0); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + } else { + vis_src1(TMP2, REF_2); + } + + ref += stride; + height = (height >> 1) - 1; + + do { /* 20 cycles */ + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP4); + + vis_ld64_2(ref, 8, TMP2); + vis_and(TMP4, MASK_fe, TMP4); + ref += stride; + + vis_ld64(ref[0], TMP8); + vis_or(REF_0, REF_2, TMP6); + vis_mul8x16(CONST_128, TMP4, TMP4); + + vis_alignaddr_g0((void *)off); + + vis_ld64_2(ref, 8, TMP10); + ref += stride; + vis_faligndata(TMP0, TMP2, REF_0); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + } else { + vis_src1(TMP2, REF_2); + } + + vis_and(TMP4, MASK_7f, TMP4); + + vis_psub16(TMP6, TMP4, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; + + vis_xor(REF_0, REF_2, TMP12); + + vis_and(TMP12, MASK_fe, TMP12); + + vis_or(REF_0, REF_2, TMP14); + vis_mul8x16(CONST_128, TMP12, TMP12); + + vis_alignaddr_g0((void *)off); + vis_faligndata(TMP8, TMP10, REF_0); + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP8, TMP10, REF_2); + } else { + vis_src1(TMP10, REF_2); + } + + vis_and(TMP12, MASK_7f, TMP12); + + vis_psub16(TMP14, TMP12, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; + } while (--height); + + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP4); + + vis_ld64_2(ref, 8, TMP2); + vis_and(TMP4, MASK_fe, TMP4); + + vis_or(REF_0, REF_2, TMP6); + vis_mul8x16(CONST_128, TMP4, TMP4); + + vis_alignaddr_g0((void *)off); + + vis_faligndata(TMP0, TMP2, REF_0); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + } else { + vis_src1(TMP2, REF_2); + } + + vis_and(TMP4, MASK_7f, TMP4); + + vis_psub16(TMP6, TMP4, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; + + vis_xor(REF_0, REF_2, TMP12); + + vis_and(TMP12, MASK_fe, TMP12); + + vis_or(REF_0, REF_2, TMP14); + vis_mul8x16(CONST_128, TMP12, TMP12); + + vis_and(TMP12, MASK_7f, TMP12); + + vis_psub16(TMP14, TMP12, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; +} + +static void MC_avg_x_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + + vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); + + vis_ld64(constants3[0], CONST_3); + vis_fzero(ZERO); + vis_ld64(constants256_512[0], CONST_256); + + ref = vis_alignaddr(ref); + do { /* 26 cycles */ + vis_ld64(ref[0], TMP0); + + vis_ld64(ref[8], TMP2); + + vis_alignaddr_g0((void *)off); + + vis_ld64(ref[16], TMP4); + + vis_ld64(dest[0], DST_0); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64(dest[8], DST_2); + vis_faligndata(TMP2, TMP4, REF_4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + vis_faligndata(TMP2, TMP4, REF_6); + } else { + vis_src1(TMP2, REF_2); + vis_src1(TMP4, REF_6); + } + + vis_mul8x16au(REF_0, CONST_256, TMP0); + + vis_pmerge(ZERO, REF_2, TMP4); + vis_mul8x16au(REF_0_1, CONST_256, TMP2); + + vis_pmerge(ZERO, REF_2_1, TMP6); + + vis_padd16(TMP0, TMP4, TMP0); + + vis_mul8x16al(DST_0, CONST_512, TMP4); + vis_padd16(TMP2, TMP6, TMP2); + + vis_mul8x16al(DST_1, CONST_512, TMP6); + + vis_mul8x16au(REF_6, CONST_256, TMP12); + + vis_padd16(TMP0, TMP4, TMP0); + vis_mul8x16au(REF_6_1, CONST_256, TMP14); + + vis_padd16(TMP2, TMP6, TMP2); + vis_mul8x16au(REF_4, CONST_256, TMP16); + + vis_padd16(TMP0, CONST_3, TMP8); + vis_mul8x16au(REF_4_1, CONST_256, TMP18); + + vis_padd16(TMP2, CONST_3, TMP10); + vis_pack16(TMP8, DST_0); + + vis_pack16(TMP10, DST_1); + vis_padd16(TMP16, TMP12, TMP0); + + vis_st64(DST_0, dest[0]); + vis_mul8x16al(DST_2, CONST_512, TMP4); + vis_padd16(TMP18, TMP14, TMP2); + + vis_mul8x16al(DST_3, CONST_512, TMP6); + vis_padd16(TMP0, CONST_3, TMP0); + + vis_padd16(TMP2, CONST_3, TMP2); + + vis_padd16(TMP0, TMP4, TMP0); + + vis_padd16(TMP2, TMP6, TMP2); + vis_pack16(TMP0, DST_2); + + vis_pack16(TMP2, DST_3); + vis_st64(DST_2, dest[8]); + + ref += stride; + dest += stride; + } while (--height); +} + +static void MC_avg_x_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + int stride_times_2 = stride << 1; + + vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); + + vis_ld64(constants3[0], CONST_3); + vis_fzero(ZERO); + vis_ld64(constants256_512[0], CONST_256); + + ref = vis_alignaddr(ref); + height >>= 2; + do { /* 47 cycles */ + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, 8, TMP2); + ref += stride; + + vis_alignaddr_g0((void *)off); + + vis_ld64(ref[0], TMP4); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, 8, TMP6); + ref += stride; + + vis_ld64(ref[0], TMP8); + + vis_ld64_2(ref, 8, TMP10); + ref += stride; + vis_faligndata(TMP4, TMP6, REF_4); + + vis_ld64(ref[0], TMP12); + + vis_ld64_2(ref, 8, TMP14); + ref += stride; + vis_faligndata(TMP8, TMP10, REF_S0); + + vis_faligndata(TMP12, TMP14, REF_S4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + + vis_ld64(dest[0], DST_0); + vis_faligndata(TMP0, TMP2, REF_2); + + vis_ld64_2(dest, stride, DST_2); + vis_faligndata(TMP4, TMP6, REF_6); + + vis_faligndata(TMP8, TMP10, REF_S2); + + vis_faligndata(TMP12, TMP14, REF_S6); + } else { + vis_ld64(dest[0], DST_0); + vis_src1(TMP2, REF_2); + + vis_ld64_2(dest, stride, DST_2); + vis_src1(TMP6, REF_6); + + vis_src1(TMP10, REF_S2); + + vis_src1(TMP14, REF_S6); + } + + vis_pmerge(ZERO, REF_0, TMP0); + vis_mul8x16au(REF_0_1, CONST_256, TMP2); + + vis_pmerge(ZERO, REF_2, TMP4); + vis_mul8x16au(REF_2_1, CONST_256, TMP6); + + vis_padd16(TMP0, CONST_3, TMP0); + vis_mul8x16al(DST_0, CONST_512, TMP16); + + vis_padd16(TMP2, CONST_3, TMP2); + vis_mul8x16al(DST_1, CONST_512, TMP18); + + vis_padd16(TMP0, TMP4, TMP0); + vis_mul8x16au(REF_4, CONST_256, TMP8); + + vis_padd16(TMP2, TMP6, TMP2); + vis_mul8x16au(REF_4_1, CONST_256, TMP10); + + vis_padd16(TMP0, TMP16, TMP0); + vis_mul8x16au(REF_6, CONST_256, TMP12); + + vis_padd16(TMP2, TMP18, TMP2); + vis_mul8x16au(REF_6_1, CONST_256, TMP14); + + vis_padd16(TMP8, CONST_3, TMP8); + vis_mul8x16al(DST_2, CONST_512, TMP16); + + vis_padd16(TMP8, TMP12, TMP8); + vis_mul8x16al(DST_3, CONST_512, TMP18); + + vis_padd16(TMP10, TMP14, TMP10); + vis_pack16(TMP0, DST_0); + + vis_pack16(TMP2, DST_1); + vis_st64(DST_0, dest[0]); + dest += stride; + vis_padd16(TMP10, CONST_3, TMP10); + + vis_ld64_2(dest, stride, DST_0); + vis_padd16(TMP8, TMP16, TMP8); + + vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/); + vis_padd16(TMP10, TMP18, TMP10); + vis_pack16(TMP8, DST_2); + + vis_pack16(TMP10, DST_3); + vis_st64(DST_2, dest[0]); + dest += stride; + + vis_mul8x16au(REF_S0_1, CONST_256, TMP2); + vis_pmerge(ZERO, REF_S0, TMP0); + + vis_pmerge(ZERO, REF_S2, TMP24); + vis_mul8x16au(REF_S2_1, CONST_256, TMP6); + + vis_padd16(TMP0, CONST_3, TMP0); + vis_mul8x16au(REF_S4, CONST_256, TMP8); + + vis_padd16(TMP2, CONST_3, TMP2); + vis_mul8x16au(REF_S4_1, CONST_256, TMP10); + + vis_padd16(TMP0, TMP24, TMP0); + vis_mul8x16au(REF_S6, CONST_256, TMP12); + + vis_padd16(TMP2, TMP6, TMP2); + vis_mul8x16au(REF_S6_1, CONST_256, TMP14); + + vis_padd16(TMP8, CONST_3, TMP8); + vis_mul8x16al(DST_0, CONST_512, TMP16); + + vis_padd16(TMP10, CONST_3, TMP10); + vis_mul8x16al(DST_1, CONST_512, TMP18); + + vis_padd16(TMP8, TMP12, TMP8); + vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20); + + vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22); + vis_padd16(TMP0, TMP16, TMP0); + + vis_padd16(TMP2, TMP18, TMP2); + vis_pack16(TMP0, DST_0); + + vis_padd16(TMP10, TMP14, TMP10); + vis_pack16(TMP2, DST_1); + vis_st64(DST_0, dest[0]); + dest += stride; + + vis_padd16(TMP8, TMP20, TMP8); + + vis_padd16(TMP10, TMP22, TMP10); + vis_pack16(TMP8, DST_2); + + vis_pack16(TMP10, DST_3); + vis_st64(DST_2, dest[0]); + dest += stride; + } while (--height); +} + +static void MC_put_y_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int offset; + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 16 : 0; + + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, 8, TMP2); + + vis_ld64_2(ref, offset, TMP4); + ref += stride; + + vis_ld64(ref[0], TMP6); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, 8, TMP8); + vis_faligndata(TMP2, TMP4, REF_4); + + vis_ld64_2(ref, offset, TMP10); + ref += stride; + + vis_ld64(constants_fe[0], MASK_fe); + vis_faligndata(TMP6, TMP8, REF_2); + + vis_ld64(constants_7f[0], MASK_7f); + vis_faligndata(TMP8, TMP10, REF_6); + + vis_ld64(constants128[0], CONST_128); + height = (height >> 1) - 1; + do { /* 24 cycles */ + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP12); + + vis_ld64_2(ref, 8, TMP2); + vis_xor(REF_4, REF_6, TMP16); + + vis_ld64_2(ref, offset, TMP4); + ref += stride; + vis_or(REF_0, REF_2, TMP14); + + vis_ld64(ref[0], TMP6); + vis_or(REF_4, REF_6, TMP18); + + vis_ld64_2(ref, 8, TMP8); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, offset, TMP10); + ref += stride; + vis_faligndata(TMP2, TMP4, REF_4); + + vis_and(TMP12, MASK_fe, TMP12); + + vis_and(TMP16, MASK_fe, TMP16); + vis_mul8x16(CONST_128, TMP12, TMP12); + + vis_mul8x16(CONST_128, TMP16, TMP16); + vis_xor(REF_0, REF_2, TMP0); + + vis_xor(REF_4, REF_6, TMP2); + + vis_or(REF_0, REF_2, TMP20); + + vis_and(TMP12, MASK_7f, TMP12); + + vis_and(TMP16, MASK_7f, TMP16); + + vis_psub16(TMP14, TMP12, TMP12); + vis_st64(TMP12, dest[0]); + + vis_psub16(TMP18, TMP16, TMP16); + vis_st64_2(TMP16, dest, 8); + dest += stride; + + vis_or(REF_4, REF_6, TMP18); + + vis_and(TMP0, MASK_fe, TMP0); + + vis_and(TMP2, MASK_fe, TMP2); + vis_mul8x16(CONST_128, TMP0, TMP0); + + vis_faligndata(TMP6, TMP8, REF_2); + vis_mul8x16(CONST_128, TMP2, TMP2); + + vis_faligndata(TMP8, TMP10, REF_6); + + vis_and(TMP0, MASK_7f, TMP0); + + vis_and(TMP2, MASK_7f, TMP2); + + vis_psub16(TMP20, TMP0, TMP0); + vis_st64(TMP0, dest[0]); + + vis_psub16(TMP18, TMP2, TMP2); + vis_st64_2(TMP2, dest, 8); + dest += stride; + } while (--height); + + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP12); + + vis_ld64_2(ref, 8, TMP2); + vis_xor(REF_4, REF_6, TMP16); + + vis_ld64_2(ref, offset, TMP4); + vis_or(REF_0, REF_2, TMP14); + + vis_or(REF_4, REF_6, TMP18); + + vis_faligndata(TMP0, TMP2, REF_0); + + vis_faligndata(TMP2, TMP4, REF_4); + + vis_and(TMP12, MASK_fe, TMP12); + + vis_and(TMP16, MASK_fe, TMP16); + vis_mul8x16(CONST_128, TMP12, TMP12); + + vis_mul8x16(CONST_128, TMP16, TMP16); + vis_xor(REF_0, REF_2, TMP0); + + vis_xor(REF_4, REF_6, TMP2); + + vis_or(REF_0, REF_2, TMP20); + + vis_and(TMP12, MASK_7f, TMP12); + + vis_and(TMP16, MASK_7f, TMP16); + + vis_psub16(TMP14, TMP12, TMP12); + vis_st64(TMP12, dest[0]); + + vis_psub16(TMP18, TMP16, TMP16); + vis_st64_2(TMP16, dest, 8); + dest += stride; + + vis_or(REF_4, REF_6, TMP18); + + vis_and(TMP0, MASK_fe, TMP0); + + vis_and(TMP2, MASK_fe, TMP2); + vis_mul8x16(CONST_128, TMP0, TMP0); + + vis_mul8x16(CONST_128, TMP2, TMP2); + + vis_and(TMP0, MASK_7f, TMP0); + + vis_and(TMP2, MASK_7f, TMP2); + + vis_psub16(TMP20, TMP0, TMP0); + vis_st64(TMP0, dest[0]); + + vis_psub16(TMP18, TMP2, TMP2); + vis_st64_2(TMP2, dest, 8); +} + +static void MC_put_y_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int offset; + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 8 : 0; + + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, offset, TMP2); + ref += stride; + + vis_ld64(ref[0], TMP4); + + vis_ld64_2(ref, offset, TMP6); + ref += stride; + + vis_ld64(constants_fe[0], MASK_fe); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64(constants_7f[0], MASK_7f); + vis_faligndata(TMP4, TMP6, REF_2); + + vis_ld64(constants128[0], CONST_128); + height = (height >> 1) - 1; + do { /* 12 cycles */ + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP4); + + vis_ld64_2(ref, offset, TMP2); + ref += stride; + vis_and(TMP4, MASK_fe, TMP4); + + vis_or(REF_0, REF_2, TMP6); + vis_mul8x16(CONST_128, TMP4, TMP4); + + vis_faligndata(TMP0, TMP2, REF_0); + vis_ld64(ref[0], TMP0); + + vis_ld64_2(ref, offset, TMP2); + ref += stride; + vis_xor(REF_0, REF_2, TMP12); + + vis_and(TMP4, MASK_7f, TMP4); + + vis_and(TMP12, MASK_fe, TMP12); + + vis_mul8x16(CONST_128, TMP12, TMP12); + vis_or(REF_0, REF_2, TMP14); + + vis_psub16(TMP6, TMP4, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; + + vis_faligndata(TMP0, TMP2, REF_2); + + vis_and(TMP12, MASK_7f, TMP12); + + vis_psub16(TMP14, TMP12, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; + } while (--height); + + vis_ld64(ref[0], TMP0); + vis_xor(REF_0, REF_2, TMP4); + + vis_ld64_2(ref, offset, TMP2); + vis_and(TMP4, MASK_fe, TMP4); + + vis_or(REF_0, REF_2, TMP6); + vis_mul8x16(CONST_128, TMP4, TMP4); + + vis_faligndata(TMP0, TMP2, REF_0); + + vis_xor(REF_0, REF_2, TMP12); + + vis_and(TMP4, MASK_7f, TMP4); + + vis_and(TMP12, MASK_fe, TMP12); + + vis_mul8x16(CONST_128, TMP12, TMP12); + vis_or(REF_0, REF_2, TMP14); + + vis_psub16(TMP6, TMP4, DST_0); + vis_st64(DST_0, dest[0]); + dest += stride; + + vis_and(TMP12, MASK_7f, TMP12); + + vis_psub16(TMP14, TMP12, DST_0); + vis_st64(DST_0, dest[0]); +} + +static void MC_avg_y_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int stride_8 = stride + 8; + int stride_16; + int offset; + + vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 16 : 0; + + vis_ld64(ref[ 0], TMP0); + vis_fzero(ZERO); + + vis_ld64(ref[ 8], TMP2); + + vis_ld64_2(ref, offset, TMP4); + stride_16 = stride + offset; + + vis_ld64(constants3[0], CONST_3); + vis_faligndata(TMP0, TMP2, REF_2); + + vis_ld64(constants256_512[0], CONST_256); + vis_faligndata(TMP2, TMP4, REF_6); + height >>= 1; + + do { /* 31 cycles */ + vis_ld64_2(ref, stride, TMP0); + vis_pmerge(ZERO, REF_2, TMP12); + vis_mul8x16au(REF_2_1, CONST_256, TMP14); + + vis_ld64_2(ref, stride_8, TMP2); + vis_pmerge(ZERO, REF_6, TMP16); + vis_mul8x16au(REF_6_1, CONST_256, TMP18); + + vis_ld64_2(ref, stride_16, TMP4); + ref += stride; + + vis_ld64(dest[0], DST_0); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(dest, 8, DST_2); + vis_faligndata(TMP2, TMP4, REF_4); + + vis_ld64_2(ref, stride, TMP6); + vis_pmerge(ZERO, REF_0, TMP0); + vis_mul8x16au(REF_0_1, CONST_256, TMP2); + + vis_ld64_2(ref, stride_8, TMP8); + vis_pmerge(ZERO, REF_4, TMP4); + + vis_ld64_2(ref, stride_16, TMP10); + ref += stride; + + vis_ld64_2(dest, stride, REF_S0/*DST_4*/); + vis_faligndata(TMP6, TMP8, REF_2); + vis_mul8x16au(REF_4_1, CONST_256, TMP6); + + vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/); + vis_faligndata(TMP8, TMP10, REF_6); + vis_mul8x16al(DST_0, CONST_512, TMP20); + + vis_padd16(TMP0, CONST_3, TMP0); + vis_mul8x16al(DST_1, CONST_512, TMP22); + + vis_padd16(TMP2, CONST_3, TMP2); + vis_mul8x16al(DST_2, CONST_512, TMP24); + + vis_padd16(TMP4, CONST_3, TMP4); + vis_mul8x16al(DST_3, CONST_512, TMP26); + + vis_padd16(TMP6, CONST_3, TMP6); + + vis_padd16(TMP12, TMP20, TMP12); + vis_mul8x16al(REF_S0, CONST_512, TMP20); + + vis_padd16(TMP14, TMP22, TMP14); + vis_mul8x16al(REF_S0_1, CONST_512, TMP22); + + vis_padd16(TMP16, TMP24, TMP16); + vis_mul8x16al(REF_S2, CONST_512, TMP24); + + vis_padd16(TMP18, TMP26, TMP18); + vis_mul8x16al(REF_S2_1, CONST_512, TMP26); + + vis_padd16(TMP12, TMP0, TMP12); + vis_mul8x16au(REF_2, CONST_256, TMP28); + + vis_padd16(TMP14, TMP2, TMP14); + vis_mul8x16au(REF_2_1, CONST_256, TMP30); + + vis_padd16(TMP16, TMP4, TMP16); + vis_mul8x16au(REF_6, CONST_256, REF_S4); + + vis_padd16(TMP18, TMP6, TMP18); + vis_mul8x16au(REF_6_1, CONST_256, REF_S6); + + vis_pack16(TMP12, DST_0); + vis_padd16(TMP28, TMP0, TMP12); + + vis_pack16(TMP14, DST_1); + vis_st64(DST_0, dest[0]); + vis_padd16(TMP30, TMP2, TMP14); + + vis_pack16(TMP16, DST_2); + vis_padd16(REF_S4, TMP4, TMP16); + + vis_pack16(TMP18, DST_3); + vis_st64_2(DST_2, dest, 8); + dest += stride; + vis_padd16(REF_S6, TMP6, TMP18); + + vis_padd16(TMP12, TMP20, TMP12); + + vis_padd16(TMP14, TMP22, TMP14); + vis_pack16(TMP12, DST_0); + + vis_padd16(TMP16, TMP24, TMP16); + vis_pack16(TMP14, DST_1); + vis_st64(DST_0, dest[0]); + + vis_padd16(TMP18, TMP26, TMP18); + vis_pack16(TMP16, DST_2); + + vis_pack16(TMP18, DST_3); + vis_st64_2(DST_2, dest, 8); + dest += stride; + } while (--height); +} + +static void MC_avg_y_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + int stride_8; + int offset; + + vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); + + ref = vis_alignaddr(ref); + offset = (ref != _ref) ? 8 : 0; + + vis_ld64(ref[ 0], TMP0); + vis_fzero(ZERO); + + vis_ld64_2(ref, offset, TMP2); + stride_8 = stride + offset; + + vis_ld64(constants3[0], CONST_3); + vis_faligndata(TMP0, TMP2, REF_2); + + vis_ld64(constants256_512[0], CONST_256); + + height >>= 1; + do { /* 20 cycles */ + vis_ld64_2(ref, stride, TMP0); + vis_pmerge(ZERO, REF_2, TMP8); + vis_mul8x16au(REF_2_1, CONST_256, TMP10); + + vis_ld64_2(ref, stride_8, TMP2); + ref += stride; + + vis_ld64(dest[0], DST_0); + + vis_ld64_2(dest, stride, DST_2); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, stride, TMP4); + vis_mul8x16al(DST_0, CONST_512, TMP16); + vis_pmerge(ZERO, REF_0, TMP12); + + vis_ld64_2(ref, stride_8, TMP6); + ref += stride; + vis_mul8x16al(DST_1, CONST_512, TMP18); + vis_pmerge(ZERO, REF_0_1, TMP14); + + vis_padd16(TMP12, CONST_3, TMP12); + vis_mul8x16al(DST_2, CONST_512, TMP24); + + vis_padd16(TMP14, CONST_3, TMP14); + vis_mul8x16al(DST_3, CONST_512, TMP26); + + vis_faligndata(TMP4, TMP6, REF_2); + + vis_padd16(TMP8, TMP12, TMP8); + + vis_padd16(TMP10, TMP14, TMP10); + vis_mul8x16au(REF_2, CONST_256, TMP20); + + vis_padd16(TMP8, TMP16, TMP0); + vis_mul8x16au(REF_2_1, CONST_256, TMP22); + + vis_padd16(TMP10, TMP18, TMP2); + vis_pack16(TMP0, DST_0); + + vis_pack16(TMP2, DST_1); + vis_st64(DST_0, dest[0]); + dest += stride; + vis_padd16(TMP12, TMP20, TMP12); + + vis_padd16(TMP14, TMP22, TMP14); + + vis_padd16(TMP12, TMP24, TMP0); + + vis_padd16(TMP14, TMP26, TMP2); + vis_pack16(TMP0, DST_2); + + vis_pack16(TMP2, DST_3); + vis_st64(DST_2, dest[0]); + dest += stride; + } while (--height); +} + +static void MC_put_xy_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + int stride_8 = stride + 8; + int stride_16 = stride + 16; + + vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); + + ref = vis_alignaddr(ref); + + vis_ld64(ref[ 0], TMP0); + vis_fzero(ZERO); + + vis_ld64(ref[ 8], TMP2); + + vis_ld64(ref[16], TMP4); + + vis_ld64(constants2[0], CONST_2); + vis_faligndata(TMP0, TMP2, REF_S0); + + vis_ld64(constants256_512[0], CONST_256); + vis_faligndata(TMP2, TMP4, REF_S4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_S2); + vis_faligndata(TMP2, TMP4, REF_S6); + } else { + vis_src1(TMP2, REF_S2); + vis_src1(TMP4, REF_S6); + } + + height >>= 1; + do { + vis_ld64_2(ref, stride, TMP0); + vis_mul8x16au(REF_S0, CONST_256, TMP12); + vis_pmerge(ZERO, REF_S0_1, TMP14); + + vis_alignaddr_g0((void *)off); + + vis_ld64_2(ref, stride_8, TMP2); + vis_mul8x16au(REF_S2, CONST_256, TMP16); + vis_pmerge(ZERO, REF_S2_1, TMP18); + + vis_ld64_2(ref, stride_16, TMP4); + ref += stride; + vis_mul8x16au(REF_S4, CONST_256, TMP20); + vis_pmerge(ZERO, REF_S4_1, TMP22); + + vis_ld64_2(ref, stride, TMP6); + vis_mul8x16au(REF_S6, CONST_256, TMP24); + vis_pmerge(ZERO, REF_S6_1, TMP26); + + vis_ld64_2(ref, stride_8, TMP8); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, stride_16, TMP10); + ref += stride; + vis_faligndata(TMP2, TMP4, REF_4); + + vis_faligndata(TMP6, TMP8, REF_S0); + + vis_faligndata(TMP8, TMP10, REF_S4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + vis_faligndata(TMP2, TMP4, REF_6); + vis_faligndata(TMP6, TMP8, REF_S2); + vis_faligndata(TMP8, TMP10, REF_S6); + } else { + vis_src1(TMP2, REF_2); + vis_src1(TMP4, REF_6); + vis_src1(TMP8, REF_S2); + vis_src1(TMP10, REF_S6); + } + + vis_mul8x16au(REF_0, CONST_256, TMP0); + vis_pmerge(ZERO, REF_0_1, TMP2); + + vis_mul8x16au(REF_2, CONST_256, TMP4); + vis_pmerge(ZERO, REF_2_1, TMP6); + + vis_padd16(TMP0, CONST_2, TMP8); + vis_mul8x16au(REF_4, CONST_256, TMP0); + + vis_padd16(TMP2, CONST_2, TMP10); + vis_mul8x16au(REF_4_1, CONST_256, TMP2); + + vis_padd16(TMP8, TMP4, TMP8); + vis_mul8x16au(REF_6, CONST_256, TMP4); + + vis_padd16(TMP10, TMP6, TMP10); + vis_mul8x16au(REF_6_1, CONST_256, TMP6); + + vis_padd16(TMP12, TMP8, TMP12); + + vis_padd16(TMP14, TMP10, TMP14); + + vis_padd16(TMP12, TMP16, TMP12); + + vis_padd16(TMP14, TMP18, TMP14); + vis_pack16(TMP12, DST_0); + + vis_pack16(TMP14, DST_1); + vis_st64(DST_0, dest[0]); + vis_padd16(TMP0, CONST_2, TMP12); + + vis_mul8x16au(REF_S0, CONST_256, TMP0); + vis_padd16(TMP2, CONST_2, TMP14); + + vis_mul8x16au(REF_S0_1, CONST_256, TMP2); + vis_padd16(TMP12, TMP4, TMP12); + + vis_mul8x16au(REF_S2, CONST_256, TMP4); + vis_padd16(TMP14, TMP6, TMP14); + + vis_mul8x16au(REF_S2_1, CONST_256, TMP6); + vis_padd16(TMP20, TMP12, TMP20); + + vis_padd16(TMP22, TMP14, TMP22); + + vis_padd16(TMP20, TMP24, TMP20); + + vis_padd16(TMP22, TMP26, TMP22); + vis_pack16(TMP20, DST_2); + + vis_pack16(TMP22, DST_3); + vis_st64_2(DST_2, dest, 8); + dest += stride; + vis_padd16(TMP0, TMP4, TMP24); + + vis_mul8x16au(REF_S4, CONST_256, TMP0); + vis_padd16(TMP2, TMP6, TMP26); + + vis_mul8x16au(REF_S4_1, CONST_256, TMP2); + vis_padd16(TMP24, TMP8, TMP24); + + vis_padd16(TMP26, TMP10, TMP26); + vis_pack16(TMP24, DST_0); + + vis_pack16(TMP26, DST_1); + vis_st64(DST_0, dest[0]); + vis_pmerge(ZERO, REF_S6, TMP4); + + vis_pmerge(ZERO, REF_S6_1, TMP6); + + vis_padd16(TMP0, TMP4, TMP0); + + vis_padd16(TMP2, TMP6, TMP2); + + vis_padd16(TMP0, TMP12, TMP0); + + vis_padd16(TMP2, TMP14, TMP2); + vis_pack16(TMP0, DST_2); + + vis_pack16(TMP2, DST_3); + vis_st64_2(DST_2, dest, 8); + dest += stride; + } while (--height); +} + +static void MC_put_xy_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + int stride_8 = stride + 8; + + vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); + + ref = vis_alignaddr(ref); + + vis_ld64(ref[ 0], TMP0); + vis_fzero(ZERO); + + vis_ld64(ref[ 8], TMP2); + + vis_ld64(constants2[0], CONST_2); + + vis_ld64(constants256_512[0], CONST_256); + vis_faligndata(TMP0, TMP2, REF_S0); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_S2); + } else { + vis_src1(TMP2, REF_S2); + } + + height >>= 1; + do { /* 26 cycles */ + vis_ld64_2(ref, stride, TMP0); + vis_mul8x16au(REF_S0, CONST_256, TMP8); + vis_pmerge(ZERO, REF_S2, TMP12); + + vis_alignaddr_g0((void *)off); + + vis_ld64_2(ref, stride_8, TMP2); + ref += stride; + vis_mul8x16au(REF_S0_1, CONST_256, TMP10); + vis_pmerge(ZERO, REF_S2_1, TMP14); + + vis_ld64_2(ref, stride, TMP4); + + vis_ld64_2(ref, stride_8, TMP6); + ref += stride; + vis_faligndata(TMP0, TMP2, REF_S4); + + vis_pmerge(ZERO, REF_S4, TMP18); + + vis_pmerge(ZERO, REF_S4_1, TMP20); + + vis_faligndata(TMP4, TMP6, REF_S0); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_S6); + vis_faligndata(TMP4, TMP6, REF_S2); + } else { + vis_src1(TMP2, REF_S6); + vis_src1(TMP6, REF_S2); + } + + vis_padd16(TMP18, CONST_2, TMP18); + vis_mul8x16au(REF_S6, CONST_256, TMP22); + + vis_padd16(TMP20, CONST_2, TMP20); + vis_mul8x16au(REF_S6_1, CONST_256, TMP24); + + vis_mul8x16au(REF_S0, CONST_256, TMP26); + vis_pmerge(ZERO, REF_S0_1, TMP28); + + vis_mul8x16au(REF_S2, CONST_256, TMP30); + vis_padd16(TMP18, TMP22, TMP18); + + vis_mul8x16au(REF_S2_1, CONST_256, TMP32); + vis_padd16(TMP20, TMP24, TMP20); + + vis_padd16(TMP8, TMP18, TMP8); + + vis_padd16(TMP10, TMP20, TMP10); + + vis_padd16(TMP8, TMP12, TMP8); + + vis_padd16(TMP10, TMP14, TMP10); + vis_pack16(TMP8, DST_0); + + vis_pack16(TMP10, DST_1); + vis_st64(DST_0, dest[0]); + dest += stride; + vis_padd16(TMP18, TMP26, TMP18); + + vis_padd16(TMP20, TMP28, TMP20); + + vis_padd16(TMP18, TMP30, TMP18); + + vis_padd16(TMP20, TMP32, TMP20); + vis_pack16(TMP18, DST_2); + + vis_pack16(TMP20, DST_3); + vis_st64(DST_2, dest[0]); + dest += stride; + } while (--height); +} + +static void MC_avg_xy_16_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + int stride_8 = stride + 8; + int stride_16 = stride + 16; + + vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); + + ref = vis_alignaddr(ref); + + vis_ld64(ref[ 0], TMP0); + vis_fzero(ZERO); + + vis_ld64(ref[ 8], TMP2); + + vis_ld64(ref[16], TMP4); + + vis_ld64(constants6[0], CONST_6); + vis_faligndata(TMP0, TMP2, REF_S0); + + vis_ld64(constants256_1024[0], CONST_256); + vis_faligndata(TMP2, TMP4, REF_S4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_S2); + vis_faligndata(TMP2, TMP4, REF_S6); + } else { + vis_src1(TMP2, REF_S2); + vis_src1(TMP4, REF_S6); + } + + height >>= 1; + do { /* 55 cycles */ + vis_ld64_2(ref, stride, TMP0); + vis_mul8x16au(REF_S0, CONST_256, TMP12); + vis_pmerge(ZERO, REF_S0_1, TMP14); + + vis_alignaddr_g0((void *)off); + + vis_ld64_2(ref, stride_8, TMP2); + vis_mul8x16au(REF_S2, CONST_256, TMP16); + vis_pmerge(ZERO, REF_S2_1, TMP18); + + vis_ld64_2(ref, stride_16, TMP4); + ref += stride; + vis_mul8x16au(REF_S4, CONST_256, TMP20); + vis_pmerge(ZERO, REF_S4_1, TMP22); + + vis_ld64_2(ref, stride, TMP6); + vis_mul8x16au(REF_S6, CONST_256, TMP24); + vis_pmerge(ZERO, REF_S6_1, TMP26); + + vis_ld64_2(ref, stride_8, TMP8); + vis_faligndata(TMP0, TMP2, REF_0); + + vis_ld64_2(ref, stride_16, TMP10); + ref += stride; + vis_faligndata(TMP2, TMP4, REF_4); + + vis_ld64(dest[0], DST_0); + vis_faligndata(TMP6, TMP8, REF_S0); + + vis_ld64_2(dest, 8, DST_2); + vis_faligndata(TMP8, TMP10, REF_S4); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_2); + vis_faligndata(TMP2, TMP4, REF_6); + vis_faligndata(TMP6, TMP8, REF_S2); + vis_faligndata(TMP8, TMP10, REF_S6); + } else { + vis_src1(TMP2, REF_2); + vis_src1(TMP4, REF_6); + vis_src1(TMP8, REF_S2); + vis_src1(TMP10, REF_S6); + } + + vis_mul8x16al(DST_0, CONST_1024, TMP30); + vis_pmerge(ZERO, REF_0, TMP0); + + vis_mul8x16al(DST_1, CONST_1024, TMP32); + vis_pmerge(ZERO, REF_0_1, TMP2); + + vis_mul8x16au(REF_2, CONST_256, TMP4); + vis_pmerge(ZERO, REF_2_1, TMP6); + + vis_mul8x16al(DST_2, CONST_1024, REF_0); + vis_padd16(TMP0, CONST_6, TMP0); + + vis_mul8x16al(DST_3, CONST_1024, REF_2); + vis_padd16(TMP2, CONST_6, TMP2); + + vis_padd16(TMP0, TMP4, TMP0); + vis_mul8x16au(REF_4, CONST_256, TMP4); + + vis_padd16(TMP2, TMP6, TMP2); + vis_mul8x16au(REF_4_1, CONST_256, TMP6); + + vis_padd16(TMP12, TMP0, TMP12); + vis_mul8x16au(REF_6, CONST_256, TMP8); + + vis_padd16(TMP14, TMP2, TMP14); + vis_mul8x16au(REF_6_1, CONST_256, TMP10); + + vis_padd16(TMP12, TMP16, TMP12); + vis_mul8x16au(REF_S0, CONST_256, REF_4); + + vis_padd16(TMP14, TMP18, TMP14); + vis_mul8x16au(REF_S0_1, CONST_256, REF_6); + + vis_padd16(TMP12, TMP30, TMP12); + + vis_padd16(TMP14, TMP32, TMP14); + vis_pack16(TMP12, DST_0); + + vis_pack16(TMP14, DST_1); + vis_st64(DST_0, dest[0]); + vis_padd16(TMP4, CONST_6, TMP4); + + vis_ld64_2(dest, stride, DST_0); + vis_padd16(TMP6, CONST_6, TMP6); + vis_mul8x16au(REF_S2, CONST_256, TMP12); + + vis_padd16(TMP4, TMP8, TMP4); + vis_mul8x16au(REF_S2_1, CONST_256, TMP14); + + vis_padd16(TMP6, TMP10, TMP6); + + vis_padd16(TMP20, TMP4, TMP20); + + vis_padd16(TMP22, TMP6, TMP22); + + vis_padd16(TMP20, TMP24, TMP20); + + vis_padd16(TMP22, TMP26, TMP22); + + vis_padd16(TMP20, REF_0, TMP20); + vis_mul8x16au(REF_S4, CONST_256, REF_0); + + vis_padd16(TMP22, REF_2, TMP22); + vis_pack16(TMP20, DST_2); + + vis_pack16(TMP22, DST_3); + vis_st64_2(DST_2, dest, 8); + dest += stride; + + vis_ld64_2(dest, 8, DST_2); + vis_mul8x16al(DST_0, CONST_1024, TMP30); + vis_pmerge(ZERO, REF_S4_1, REF_2); + + vis_mul8x16al(DST_1, CONST_1024, TMP32); + vis_padd16(REF_4, TMP0, TMP8); + + vis_mul8x16au(REF_S6, CONST_256, REF_4); + vis_padd16(REF_6, TMP2, TMP10); + + vis_mul8x16au(REF_S6_1, CONST_256, REF_6); + vis_padd16(TMP8, TMP12, TMP8); + + vis_padd16(TMP10, TMP14, TMP10); + + vis_padd16(TMP8, TMP30, TMP8); + + vis_padd16(TMP10, TMP32, TMP10); + vis_pack16(TMP8, DST_0); + + vis_pack16(TMP10, DST_1); + vis_st64(DST_0, dest[0]); + + vis_padd16(REF_0, TMP4, REF_0); + + vis_mul8x16al(DST_2, CONST_1024, TMP30); + vis_padd16(REF_2, TMP6, REF_2); + + vis_mul8x16al(DST_3, CONST_1024, TMP32); + vis_padd16(REF_0, REF_4, REF_0); + + vis_padd16(REF_2, REF_6, REF_2); + + vis_padd16(REF_0, TMP30, REF_0); + + /* stall */ + + vis_padd16(REF_2, TMP32, REF_2); + vis_pack16(REF_0, DST_2); + + vis_pack16(REF_2, DST_3); + vis_st64_2(DST_2, dest, 8); + dest += stride; + } while (--height); +} + +static void MC_avg_xy_8_vis (uint8_t * dest, uint8_t * _ref, + int stride, int height) +{ + uint8_t *ref = (uint8_t *) _ref; + unsigned long off = (unsigned long) ref & 0x7; + unsigned long off_plus_1 = off + 1; + int stride_8 = stride + 8; + + vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); + + ref = vis_alignaddr(ref); + + vis_ld64(ref[0], TMP0); + vis_fzero(ZERO); + + vis_ld64_2(ref, 8, TMP2); + + vis_ld64(constants6[0], CONST_6); + + vis_ld64(constants256_1024[0], CONST_256); + vis_faligndata(TMP0, TMP2, REF_S0); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_S2); + } else { + vis_src1(TMP2, REF_S2); + } + + height >>= 1; + do { /* 31 cycles */ + vis_ld64_2(ref, stride, TMP0); + vis_mul8x16au(REF_S0, CONST_256, TMP8); + vis_pmerge(ZERO, REF_S0_1, TMP10); + + vis_ld64_2(ref, stride_8, TMP2); + ref += stride; + vis_mul8x16au(REF_S2, CONST_256, TMP12); + vis_pmerge(ZERO, REF_S2_1, TMP14); + + vis_alignaddr_g0((void *)off); + + vis_ld64_2(ref, stride, TMP4); + vis_faligndata(TMP0, TMP2, REF_S4); + + vis_ld64_2(ref, stride_8, TMP6); + ref += stride; + + vis_ld64(dest[0], DST_0); + vis_faligndata(TMP4, TMP6, REF_S0); + + vis_ld64_2(dest, stride, DST_2); + + if (off != 0x7) { + vis_alignaddr_g0((void *)off_plus_1); + vis_faligndata(TMP0, TMP2, REF_S6); + vis_faligndata(TMP4, TMP6, REF_S2); + } else { + vis_src1(TMP2, REF_S6); + vis_src1(TMP6, REF_S2); + } + + vis_mul8x16al(DST_0, CONST_1024, TMP30); + vis_pmerge(ZERO, REF_S4, TMP22); + + vis_mul8x16al(DST_1, CONST_1024, TMP32); + vis_pmerge(ZERO, REF_S4_1, TMP24); + + vis_mul8x16au(REF_S6, CONST_256, TMP26); + vis_pmerge(ZERO, REF_S6_1, TMP28); + + vis_mul8x16au(REF_S0, CONST_256, REF_S4); + vis_padd16(TMP22, CONST_6, TMP22); + + vis_mul8x16au(REF_S0_1, CONST_256, REF_S6); + vis_padd16(TMP24, CONST_6, TMP24); + + vis_mul8x16al(DST_2, CONST_1024, REF_0); + vis_padd16(TMP22, TMP26, TMP22); + + vis_mul8x16al(DST_3, CONST_1024, REF_2); + vis_padd16(TMP24, TMP28, TMP24); + + vis_mul8x16au(REF_S2, CONST_256, TMP26); + vis_padd16(TMP8, TMP22, TMP8); + + vis_mul8x16au(REF_S2_1, CONST_256, TMP28); + vis_padd16(TMP10, TMP24, TMP10); + + vis_padd16(TMP8, TMP12, TMP8); + + vis_padd16(TMP10, TMP14, TMP10); + + vis_padd16(TMP8, TMP30, TMP8); + + vis_padd16(TMP10, TMP32, TMP10); + vis_pack16(TMP8, DST_0); + + vis_pack16(TMP10, DST_1); + vis_st64(DST_0, dest[0]); + dest += stride; + + vis_padd16(REF_S4, TMP22, TMP12); + + vis_padd16(REF_S6, TMP24, TMP14); + + vis_padd16(TMP12, TMP26, TMP12); + + vis_padd16(TMP14, TMP28, TMP14); + + vis_padd16(TMP12, REF_0, TMP12); + + vis_padd16(TMP14, REF_2, TMP14); + vis_pack16(TMP12, DST_2); + + vis_pack16(TMP14, DST_3); + vis_st64(DST_2, dest[0]); + dest += stride; + } while (--height); +} + +MPEG2_MC_EXTERN(vis); + +#endif /* defined(ARCH_SPARC) && defined(ENABLE_VIS) */ diff --git a/src/video_dec/libmpeg2/mpeg2.h b/src/video_dec/libmpeg2/mpeg2.h new file mode 100644 index 000000000..253f300a2 --- /dev/null +++ b/src/video_dec/libmpeg2/mpeg2.h @@ -0,0 +1,98 @@ +/* + * mpeg2.h + * Copyright (C) 1999-2001 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/* Structure for the mpeg2dec decoder */ + +#ifndef MPEG2_H +#define MPEG2_H + +#include "libmpeg2_accel.h" + +typedef struct mpeg2dec_s { + xine_video_port_t * output; + uint32_t frame_format; + + /* this is where we keep the state of the decoder */ + struct picture_s * picture, *picture_base; + + uint32_t shift; + int new_sequence; + int is_sequence_needed; + int is_wait_for_ip_frames; + int frames_to_drop, drop_frame; + int in_slice; + int seek_mode, is_frame_needed; + + /* the maximum chunk size is determined by vbv_buffer_size */ + /* which is 224K for MP@ML streams. */ + /* (we make no pretenses of decoding anything more than that) */ + /* allocated in init - gcc has problems allocating such big structures */ + uint8_t * chunk_buffer, *chunk_base; + /* pointer to current position in chunk_buffer */ + uint8_t * chunk_ptr; + /* last start code ? */ + uint8_t code; + uint32_t chunk_size; + + int64_t pts; + uint32_t rff_pattern; + int force_aspect; + int force_pan_scan; + + /* AFD data can be found after a sequence, group or picture start code */ + /* and will be stored in afd_value_seen. Later it will be transfered to */ + /* a stream property and stored into afd_value_reported to detect changes */ + int afd_value_seen; + int afd_value_reported; + + xine_stream_t *stream; + + /* a spu decoder for possible closed captions */ + spu_decoder_t *cc_dec; + mpeg2dec_accel_t accel; + +} mpeg2dec_t ; + + +/* initialize mpegdec with a opaque user pointer */ +void mpeg2_init (mpeg2dec_t * mpeg2dec, + xine_video_port_t * output); + +/* destroy everything which was allocated, shutdown the output */ +void mpeg2_close (mpeg2dec_t * mpeg2dec); + +int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, + uint8_t * data_start, uint8_t * data_end, + uint64_t pts); + +void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec, + uint8_t * data_start, uint8_t * data_end); + +void mpeg2_flush (mpeg2dec_t * mpeg2dec); +void mpeg2_reset (mpeg2dec_t * mpeg2dec); +void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec); + +/* Not needed, it is defined as static in decode.c, and no-one else called it + * currently + */ +/* void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); */ + +#endif diff --git a/src/video_dec/libmpeg2/mpeg2_internal.h b/src/video_dec/libmpeg2/mpeg2_internal.h new file mode 100644 index 000000000..2e42aace6 --- /dev/null +++ b/src/video_dec/libmpeg2/mpeg2_internal.h @@ -0,0 +1,294 @@ +/* + * mpeg2_internal.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#ifndef MPEG2_INTERNAL_H +#define MPEG2_INTERNAL_H + +#include +#include "accel_xvmc.h" + +#ifdef ENABLE_ALTIVEC +#include +#endif + +/* macroblock modes */ +#define MACROBLOCK_INTRA XINE_MACROBLOCK_INTRA +#define MACROBLOCK_PATTERN XINE_MACROBLOCK_PATTERN +#define MACROBLOCK_MOTION_BACKWARD XINE_MACROBLOCK_MOTION_BACKWARD +#define MACROBLOCK_MOTION_FORWARD XINE_MACROBLOCK_MOTION_FORWARD +#define MACROBLOCK_QUANT XINE_MACROBLOCK_QUANT +#define DCT_TYPE_INTERLACED XINE_MACROBLOCK_DCT_TYPE_INTERLACED + +/* motion_type */ +#define MOTION_TYPE_MASK (3*64) +#define MOTION_TYPE_BASE 64 +#define MC_FIELD (1*64) +#define MC_FRAME (2*64) +#define MC_16X8 (2*64) +#define MC_DMV (3*64) + +/* picture structure */ +#define TOP_FIELD VO_TOP_FIELD +#define BOTTOM_FIELD VO_BOTTOM_FIELD +#define FRAME_PICTURE VO_BOTH_FIELDS + +/* picture coding type (mpeg2 header) */ +#define I_TYPE 1 +#define P_TYPE 2 +#define B_TYPE 3 +#define D_TYPE 4 + +typedef struct motion_s { + uint8_t * ref[2][3]; + uint8_t ** ref2[2]; + int pmv[2][2]; + int f_code[2]; +} motion_t; + +typedef struct picture_s { + /* first, state that carries information from one macroblock to the */ + /* next inside a slice, and is never used outside of mpeg2_slice() */ + + /* DCT coefficients - should be kept aligned ! */ + int16_t DCTblock[64]; + + /* XvMC DCT block and macroblock data for XvMC acceleration */ + xine_macroblocks_t *mc; + int XvMC_mb_type; + int XvMC_mv_field_sel[2][2]; + int XvMC_x; + int XvMC_y; + int XvMC_motion_type; + int XvMC_dmvector[2]; + int XvMC_cbp; + int XvMC_dct_type; + + /* bit parsing stuff */ + uint32_t bitstream_buf; /* current 32 bit working set of buffer */ + int bitstream_bits; /* used bits in working set */ + uint8_t * bitstream_ptr; /* buffer with stream data */ + + uint8_t * dest[3]; + int pitches[3]; + int offset; + unsigned int limit_x; + unsigned int limit_y_16; + unsigned int limit_y_8; + unsigned int limit_y; + + /* Motion vectors */ + /* The f_ and b_ correspond to the forward and backward motion */ + /* predictors */ + motion_t b_motion; + motion_t f_motion; + + /* predictor for DC coefficients in intra blocks */ + int16_t dc_dct_pred[3]; + + int quantizer_scale; /* remove */ + int current_field; /* remove */ + int dmv_offset; /* remove */ + unsigned int v_offset; /* remove */ + + + /* now non-slice-specific information */ + + /* sequence header stuff */ + uint8_t intra_quantizer_matrix [64]; + uint8_t non_intra_quantizer_matrix [64]; + int load_intra_quantizer_matrix; + int load_non_intra_quantizer_matrix; + + /* The width and height of the picture snapped to macroblock units */ + int coded_picture_width; + int coded_picture_height; + + /* The width and height as it appears on header sequence */ + unsigned int display_width, display_height; + + /* picture header stuff */ + + /* what type of picture this is (I, P, B, D) */ + int picture_coding_type; + + int vbv_delay; + int low_delay; + + /* picture coding extension stuff */ + + /* quantization factor for intra dc coefficients */ + int intra_dc_precision; + /* top/bottom/both fields */ + int picture_structure; + /* bool to indicate all predictions are frame based */ + int frame_pred_frame_dct; + /* bool to indicate whether intra blocks have motion vectors */ + /* (for concealment) */ + int concealment_motion_vectors; + /* bit to indicate which quantization table to use */ + int q_scale_type; + /* bool to use different vlc tables */ + int intra_vlc_format; + /* used for DMV MC */ + int top_field_first; + + /* stuff derived from bitstream */ + + /* pointer to the zigzag scan we're supposed to be using */ + uint8_t * scan; + + struct vo_frame_s * current_frame; + struct vo_frame_s * forward_reference_frame; + struct vo_frame_s * backward_reference_frame; + + int frame_width, frame_height; + + int second_field; + + int mpeg1; + + int skip_non_intra_dct; + + /* these things are not needed by the decoder */ + /* this is a temporary interface, we will build a better one later. */ + int aspect_ratio_information; + int saved_aspect_ratio; + int frame_rate_code; + int progressive_sequence; + int repeat_first_field; + int progressive_frame; + uint32_t frame_centre_horizontal_offset; + uint32_t frame_centre_vertical_offset; + uint32_t video_format; + uint32_t colour_description; + uint32_t colour_primatives; + uint32_t transfer_characteristics; + uint32_t matrix_coefficients; + uint32_t display_horizontal_size; + uint32_t display_vertical_size; + uint32_t drop_frame_flag; + uint32_t time_code_hours; + uint32_t time_code_minutes; + uint32_t time_code_seconds; + uint32_t time_code_pictures; + uint32_t closed_gop; + uint32_t broken_link; + + int bitrate; + int frame_rate_ext_n; + int frame_rate_ext_d; + +} picture_t; + +typedef struct cpu_state_s { +#ifdef ARCH_PPC + uint8_t regv[12*16]; +#endif + int dummy; +} cpu_state_t; + +/* cpu_state.c */ +extern void (* mpeg2_cpu_state_save) (cpu_state_t * state); +extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state); +void mpeg2_cpu_state_init (uint32_t mm_accel); + +/* header.c */ +extern uint8_t mpeg2_scan_norm[64]; +extern uint8_t mpeg2_scan_alt[64]; +void mpeg2_header_state_init (picture_t * picture); +int mpeg2_header_picture (picture_t * picture, uint8_t * buffer); +int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer); +int mpeg2_header_extension (picture_t * picture, uint8_t * buffer); +int mpeg2_header_group_of_pictures (picture_t * picture, uint8_t * buffer); + +/* idct.c */ +extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); +extern void (* mpeg2_idct_add) (int16_t * block, uint8_t * dest, int stride); +extern void (* mpeg2_idct) (int16_t * block); +extern void (* mpeg2_zero_block) (int16_t * block); +void mpeg2_idct_init (uint32_t mm_accel); + +/* idct_mlib.c */ +void mpeg2_idct_add_mlib (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, + int stride); +void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, + int stride); +void mpeg2_idct_mlib (int16_t * block); + +/* idct_mmx.c */ +void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_mmxext (int16_t * block); +void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_mmx (int16_t * block); +void mpeg2_zero_block_mmx (int16_t * block); +void mpeg2_idct_mmx_init (void); + +/* idct_altivec.c */ +# ifdef ENABLE_ALTIVEC +void mpeg2_idct_copy_altivec (vector signed short * block, unsigned char * dest, + int stride); +void mpeg2_idct_add_altivec (vector signed short * block, unsigned char * dest, + int stride); +# else /* ! ENABLE_ALTIVEC */ +void mpeg2_idct_copy_altivec (signed short * block, unsigned char * dest, + int stride); +void mpeg2_idct_add_altivec (signed short * block, unsigned char * dest, + int stride); +# endif /* ENABLE_ALTIVEC */ +void mpeg2_idct_altivec_init (void); + +/* motion_comp.c */ +void mpeg2_mc_init (uint32_t mm_accel); + +typedef struct mpeg2_mc_s { + void (* put [8]) (uint8_t * dst, uint8_t *, int32_t, int32_t); + void (* avg [8]) (uint8_t * dst, uint8_t *, int32_t, int32_t); +} mpeg2_mc_t; + +#define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \ + {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \ + MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \ + {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \ + MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \ +}; + +extern mpeg2_mc_t mpeg2_mc; +extern mpeg2_mc_t mpeg2_mc_c; +extern mpeg2_mc_t mpeg2_mc_mmx; +extern mpeg2_mc_t mpeg2_mc_mmxext; +extern mpeg2_mc_t mpeg2_mc_3dnow; +extern mpeg2_mc_t mpeg2_mc_altivec; +extern mpeg2_mc_t mpeg2_mc_mlib; +extern mpeg2_mc_t mpeg2_mc_vis; + +/* slice.c */ +void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer); + +/* stats.c */ +void mpeg2_stats (int code, uint8_t * buffer); + + +#endif diff --git a/src/video_dec/libmpeg2/slice.c b/src/video_dec/libmpeg2/slice.c new file mode 100644 index 000000000..8247a9a24 --- /dev/null +++ b/src/video_dec/libmpeg2/slice.c @@ -0,0 +1,1833 @@ +/* + * slice.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include + +#include +#include +#include "mpeg2_internal.h" +#include + +#include "vlc.h" + +static const int non_linear_quantizer_scale [] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 18, 20, 22, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 104, 112 +}; + +static inline int get_macroblock_modes (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int macroblock_modes; + const MBtab * tab; + + switch (picture->picture_coding_type) { + case I_TYPE: + + tab = MB_I + UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if ((! (picture->frame_pred_frame_dct)) && + (picture->picture_structure == FRAME_PICTURE)) { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + + return macroblock_modes; + + case P_TYPE: + + tab = MB_P + UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (picture->picture_structure != FRAME_PICTURE) { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } else if (picture->frame_pred_frame_dct) { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } else { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case B_TYPE: + + tab = MB_B + UBITS (bit_buf, 6); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (picture->picture_structure != FRAME_PICTURE) { + if (! (macroblock_modes & MACROBLOCK_INTRA)) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } else if (picture->frame_pred_frame_dct) { + /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } else { + if (macroblock_modes & MACROBLOCK_INTRA) + goto intra; + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { + intra: + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case D_TYPE: + + DUMPBITS (bit_buf, bits, 1); + return MACROBLOCK_INTRA; + + default: + return 0; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_quantizer_scale (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + int quantizer_scale_code; + + quantizer_scale_code = UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, 5); + + if (picture->q_scale_type) + return non_linear_quantizer_scale [quantizer_scale_code]; + else + return quantizer_scale_code << 1; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_motion_delta (picture_t * picture, int f_code) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + int delta; + int sign; + const MVtab * tab; + + if (bit_buf & 0x80000000) { + DUMPBITS (bit_buf, bits, 1); + return 0; + } else if (bit_buf >= 0x0c000000) { + + tab = MV_4 + UBITS (bit_buf, 4); + delta = (tab->delta << f_code) + 1; + bits += tab->len + f_code + 1; + bit_buf <<= tab->len; + + sign = SBITS (bit_buf, 1); + bit_buf <<= 1; + + if (f_code) + delta += UBITS (bit_buf, f_code); + bit_buf <<= f_code; + + return (delta ^ sign) - sign; + + } else { + + tab = MV_10 + UBITS (bit_buf, 10); + delta = (tab->delta << f_code) + 1; + bits += tab->len + 1; + bit_buf <<= tab->len; + + sign = SBITS (bit_buf, 1); + bit_buf <<= 1; + + if (f_code) { + NEEDBITS (bit_buf, bits, bit_ptr); + delta += UBITS (bit_buf, f_code); + DUMPBITS (bit_buf, bits, f_code); + } + + return (delta ^ sign) - sign; + + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int bound_motion_vector (int vec, int f_code) +{ +#if 1 + unsigned int limit; + int sign; + + limit = 16 << f_code; + + if ((unsigned int)(vec + limit) < 2 * limit) + return vec; + else { + sign = ((int32_t)vec) >> 31; + return vec - ((2 * limit) ^ sign) + sign; + } +#else + return ((int32_t)vector << (27 - f_code)) >> (27 - f_code); +#endif +} + +static inline int get_dmv (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + const DMVtab * tab; + + tab = DMV_2 + UBITS (bit_buf, 2); + DUMPBITS (bit_buf, bits, tab->len); + return tab->dmv; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_coded_block_pattern (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + const CBPtab * tab; + + NEEDBITS (bit_buf, bits, bit_ptr); + + if (bit_buf >= 0x20000000) { + + tab = CBP_7 + (UBITS (bit_buf, 7) - 16); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + + } else { + + tab = CBP_9 + UBITS (bit_buf, 9); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + } + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_luma_dc_dct_diff (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + const DCtab * tab; + int size; + int dc_diff; + + if (bit_buf < 0xf8000000) { + tab = DC_lum_5 + UBITS (bit_buf, 5); + size = tab->size; + if (size) { + bits += tab->len + size; + bit_buf <<= tab->len; + dc_diff = + UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + bit_buf <<= size; + return dc_diff; + } else { + DUMPBITS (bit_buf, bits, 3); + return 0; + } + } else { + tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len); + NEEDBITS (bit_buf, bits, bit_ptr); + dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + DUMPBITS (bit_buf, bits, size); + return dc_diff; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_chroma_dc_dct_diff (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + const DCtab * tab; + int size; + int dc_diff; + + if (bit_buf < 0xf8000000) { + tab = DC_chrom_5 + UBITS (bit_buf, 5); + size = tab->size; + if (size) { + bits += tab->len + size; + bit_buf <<= tab->len; + dc_diff = + UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + bit_buf <<= size; + return dc_diff; + } else { + DUMPBITS (bit_buf, bits, 2); + return 0; + } + } else { + tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len + 1); + NEEDBITS (bit_buf, bits, bit_ptr); + dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + DUMPBITS (bit_buf, bits, size); + return dc_diff; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +#define SATURATE(val) \ +do { \ + if ((uint32_t)(val + 2048) > 4095) \ + val = (val > 0) ? 2047 : -2048; \ +} while (0) + +static void get_intra_block_B14 (picture_t * picture) +{ + int i; + int j; + int val; + uint8_t * scan = picture->scan; + uint8_t * quant_matrix = picture->intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + dest = picture->DCTblock; + i = 0; + mismatch = ~dest[0]; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = (SBITS (bit_buf, 12) * + quantizer_scale * quant_matrix[j]) / 16; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_intra_block_B15 (picture_t * picture) +{ + int i; + int j; + int val; + uint8_t * scan = picture->scan; + uint8_t * quant_matrix = picture->intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + dest = picture->DCTblock; + i = 0; + mismatch = ~dest[0]; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x04000000) { + + tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) { + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else { + + /* end of block. I commented out this code because if we */ + /* dont exit here we will still exit at the later test :) */ + + /* if (i >= 128) break; */ /* end of block */ + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check against buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = (SBITS (bit_buf, 12) * + quantizer_scale * quant_matrix[j]) / 16; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + } else if (bit_buf >= 0x02000000) { + tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_non_intra_block (picture_t * picture) +{ + int i; + int j; + int val; + uint8_t * scan = picture->scan; + uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + i = -1; + mismatch = 1; + dest = picture->DCTblock; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + if (bit_buf >= 0x28000000) { + tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); + goto entry_1; + } else + goto entry_2; + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + + entry_2: + if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; + val = (val * quantizer_scale * quant_matrix[j]) / 32; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_mpeg1_intra_block (picture_t * picture) +{ + int i; + int j; + int val; + uint8_t * scan = picture->scan; + uint8_t * quant_matrix = picture->intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + i = 0; + dest = picture->DCTblock; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; + + /* oddification */ + val = (val - 1) | 1; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = SBITS (bit_buf, 8); + if (! (val & 0x7f)) { + DUMPBITS (bit_buf, bits, 8); + val = UBITS (bit_buf, 8) + 2 * val; + } + val = (val * quantizer_scale * quant_matrix[j]) / 16; + + /* oddification */ + val = (val + ~SBITS (val, 1)) | 1; + + SATURATE (val); + dest[j] = val; + + DUMPBITS (bit_buf, bits, 8); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_mpeg1_non_intra_block (picture_t * picture) +{ + int i; + int j; + int val; + uint8_t * scan = picture->scan; + uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + i = -1; + dest = picture->DCTblock; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + if (bit_buf >= 0x28000000) { + tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); + goto entry_1; + } else + goto entry_2; + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; + + /* oddification */ + val = (val - 1) | 1; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + + entry_2: + if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = SBITS (bit_buf, 8); + if (! (val & 0x7f)) { + DUMPBITS (bit_buf, bits, 8); + val = UBITS (bit_buf, 8) + 2 * val; + } + val = 2 * (val + SBITS (val, 1)) + 1; + val = (val * quantizer_scale * quant_matrix[j]) / 32; + + /* oddification */ + val = (val + ~SBITS (val, 1)) | 1; + + SATURATE (val); + dest[j] = val; + + DUMPBITS (bit_buf, bits, 8); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static inline void slice_intra_DCT (picture_t * picture, int cc, + uint8_t * dest, int stride) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + NEEDBITS (bit_buf, bits, bit_ptr); + /* Get the intra DC coefficient and inverse quantize it */ + if (cc == 0) + picture->dc_dct_pred[0] += get_luma_dc_dct_diff (picture); + else + picture->dc_dct_pred[cc] += get_chroma_dc_dct_diff (picture); + picture->DCTblock[0] = + picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision); + + if (picture->mpeg1) { + if (picture->picture_coding_type != D_TYPE) + get_mpeg1_intra_block (picture); + } else if (picture->intra_vlc_format) + get_intra_block_B15 (picture); + else + get_intra_block_B14 (picture); + mpeg2_idct_copy (picture->DCTblock, dest, stride); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline void slice_non_intra_DCT (picture_t * picture, uint8_t * dest, + int stride) +{ + if (picture->mpeg1) + get_mpeg1_non_intra_block (picture); + else + get_non_intra_block (picture); + mpeg2_idct_add (picture->DCTblock, dest, stride); +} + +#define MOTION(table,ref,motion_x,motion_y,size,y) \ + pos_x = 2 * picture->offset + motion_x; \ + pos_y = 2 * picture->v_offset + motion_y + 2 * y; \ + if (pos_x > picture->limit_x) { \ + pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; \ + motion_x = pos_x - 2 * picture->offset; \ + } \ + if (pos_y > picture->limit_y_ ## size){ \ + pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y_ ## size; \ + motion_y = pos_y - 2 * picture->v_offset - 2 * y; \ + } \ + xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ + table[xy_half] (picture->dest[0] + y * picture->pitches[0] + \ + picture->offset, ref[0] + (pos_x >> 1) + \ + (pos_y >> 1) * picture->pitches[0], picture->pitches[0], \ + size); \ + motion_x /= 2; motion_y /= 2; \ + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ + table[4+xy_half] (picture->dest[1] + y/2 * picture->pitches[1] + \ + (picture->offset >> 1), ref[1] + \ + (((picture->offset + motion_x) >> 1) + \ + ((((picture->v_offset + motion_y) >> 1) + y/2) * \ + picture->pitches[1])), picture->pitches[1], size/2); \ + table[4+xy_half] (picture->dest[2] + y/2 * picture->pitches[2] + \ + (picture->offset >> 1), ref[2] + \ + (((picture->offset + motion_x) >> 1) + \ + ((((picture->v_offset + motion_y) >> 1) + y/2) * \ + picture->pitches[2])), picture->pitches[2], size/2) \ + +#define MOTION_FIELD(table,ref,motion_x,motion_y,dest_field,op,src_field) \ + pos_x = 2 * picture->offset + motion_x; \ + pos_y = picture->v_offset + motion_y; \ + if (pos_x > picture->limit_x) { \ + pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; \ + motion_x = pos_x - 2 * picture->offset; \ + } \ + if (pos_y > picture->limit_y){ \ + pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y; \ + motion_y = pos_y - picture->v_offset; \ + } \ + xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ + table[xy_half] (picture->dest[0] + dest_field * picture->pitches[0] + \ + picture->offset, \ + (ref[0] + (pos_x >> 1) + \ + ((pos_y op) + src_field) * picture->pitches[0]), \ + 2 * picture->pitches[0], 8); \ + motion_x /= 2; motion_y /= 2; \ + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ + table[4+xy_half] (picture->dest[1] + dest_field * picture->pitches[1] + \ + (picture->offset >> 1), ref[1] + \ + (((picture->offset + motion_x) >> 1) + \ + (((picture->v_offset >> 1) + \ + (motion_y op) + src_field) * picture->pitches[1])), \ + 2 * picture->pitches[1], 4); \ + table[4+xy_half] (picture->dest[2] + dest_field * picture->pitches[2] + \ + (picture->offset >> 1), ref[2] + \ + (((picture->offset + motion_x) >> 1) + \ + (((picture->v_offset >> 1) + \ + (motion_y op) + src_field) * picture->pitches[2])), \ + 2 * picture->pitches[2], 4) + +static void motion_mp1 (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = (motion->pmv[0][0] + + (get_motion_delta (picture, + motion->f_code[0]) << motion->f_code[1])); + motion_x = bound_motion_vector (motion_x, + motion->f_code[0] + motion->f_code[1]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[0][1] + + (get_motion_delta (picture, + motion->f_code[0]) << motion->f_code[1])); + motion_y = bound_motion_vector (motion_y, + motion->f_code[0] + motion->f_code[1]); + motion->pmv[0][1] = motion_y; + + MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_frame (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + + MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_field (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y, field; + unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + field = UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[0][1] = motion_y << 1; + + MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); + + NEEDBITS (bit_buf, bits, bit_ptr); + field = UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[1][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (picture, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[1][1] = motion_y << 1; + + MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_dmv (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + NEEDBITS (bit_buf, bits, bit_ptr); + dmv_x = get_dmv (picture); + + motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; + dmv_y = get_dmv (picture); + + m = picture->top_field_first ? 1 : 3; + other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; + other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; + MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); + + m = picture->top_field_first ? 3 : 1; + other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; + other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; + MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0); + + pos_x = 2 * picture->offset + motion_x; + pos_y = picture->v_offset + motion_y; + if(pos_x > picture->limit_x){ + pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; + motion_x = pos_x - 2 * picture->offset; + } + if(pos_y > picture->limit_y){ + pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y; + motion_y = pos_y - picture->v_offset; + } + xy_half = ((pos_y & 1) << 1) | (pos_x & 1); + offset = (pos_x >> 1) + (pos_y & ~1) * picture->pitches[0]; + mpeg2_mc.avg[xy_half] + (picture->dest[0] + picture->offset, + motion->ref[0][0] + offset, 2 * picture->pitches[0], 8); + mpeg2_mc.avg[xy_half] + (picture->dest[0] + picture->pitches[0] + picture->offset, + motion->ref[0][0] + picture->pitches[0] + offset, + 2 * picture->pitches[0], 8); + motion_x /= 2; motion_y /= 2; + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); + offset = (((picture->offset + motion_x) >> 1) + + (((picture->v_offset >> 1) + (motion_y & ~1)) * + picture->pitches[1])); + mpeg2_mc.avg[4+xy_half] + (picture->dest[1] + (picture->offset >> 1), + motion->ref[0][1] + offset, 2 * picture->pitches[1], 4); + mpeg2_mc.avg[4+xy_half] + (picture->dest[1] + picture->pitches[1] + (picture->offset >> 1), + motion->ref[0][1] + picture->pitches[1] + offset, + 2 * picture->pitches[1], 4); + offset = (((picture->offset + motion_x) >> 1) + + (((picture->v_offset >> 1) + (motion_y & ~1)) * + picture->pitches[2])); + mpeg2_mc.avg[4+xy_half] + (picture->dest[2] + (picture->offset >> 1), + motion->ref[0][2] + offset, 2 * picture->pitches[2], 4); + mpeg2_mc.avg[4+xy_half] + (picture->dest[2] + picture->pitches[2] + (picture->offset >> 1), + motion->ref[0][2] + picture->pitches[2] + offset, + 2 * picture->pitches[2], 4); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_reuse (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ + int motion_x, motion_y; + unsigned int pos_x, pos_y, xy_half; + + motion_x = motion->pmv[0][0]; + motion_y = motion->pmv[0][1]; + + MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); +} + +static void motion_zero (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ + table[0] (picture->dest[0] + picture->offset, + (motion->ref[0][0] + picture->offset + + picture->v_offset * picture->pitches[0]), + picture->pitches[0], 16); + + table[4] (picture->dest[1] + (picture->offset >> 1), + motion->ref[0][1] + (picture->offset >> 1) + + (picture->v_offset >> 1) * picture->pitches[1], + picture->pitches[1], 8); + table[4] (picture->dest[2] + (picture->offset >> 1), + motion->ref[0][2] + (picture->offset >> 1) + + (picture->v_offset >> 1) * picture->pitches[2], + picture->pitches[2], 8); +} + +/* like motion_frame, but parsing without actual motion compensation */ +static void motion_fr_conceal (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (picture->f_motion.pmv[0][0] + + get_motion_delta (picture, picture->f_motion.f_code[0])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (picture->f_motion.pmv[0][1] + + get_motion_delta (picture, picture->f_motion.f_code[1])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); + picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; + + DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_field (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + uint8_t ** ref_field; + unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + + MOTION (table, ref_field, motion_x, motion_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_16x8 (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + uint8_t ** ref_field; + unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[0][1] = motion_y; + + MOTION (table, ref_field, motion_x, motion_y, 8, 0); + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[1][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[1][1] + get_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion_y; + + MOTION (table, ref_field, motion_x, motion_y, 8, 8); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_dmv (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y, other_x, other_y; + unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + NEEDBITS (bit_buf, bits, bit_ptr); + other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (picture); + + motion_y = motion->pmv[0][1] + get_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (picture) + + picture->dmv_offset); + + MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); + MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_conceal (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); /* remove field_select */ + + tmp = (picture->f_motion.pmv[0][0] + + get_motion_delta (picture, picture->f_motion.f_code[0])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (picture->f_motion.pmv[0][1] + + get_motion_delta (picture, picture->f_motion.f_code[1])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); + picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; + + DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ +#undef bit_buf +#undef bits +#undef bit_ptr +} + +#define MOTION_CALL(routine,direction) \ +do { \ + if ((direction) & MACROBLOCK_MOTION_FORWARD) \ + routine (picture, &(picture->f_motion), mpeg2_mc.put); \ + if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ + routine (picture, &(picture->b_motion), \ + ((direction) & MACROBLOCK_MOTION_FORWARD ? \ + mpeg2_mc.avg : mpeg2_mc.put)); \ +} while (0) + +#define NEXT_MACROBLOCK \ +do { \ + picture->offset += 16; \ + if (picture->offset == picture->coded_picture_width) { \ + do { /* just so we can use the break statement */ \ + if (picture->current_frame->proc_slice) { \ + picture->current_frame->proc_slice (picture->current_frame, \ + picture->dest); \ + } \ + picture->dest[0] += 16 * picture->pitches[0]; \ + picture->dest[1] += 8 * picture->pitches[1]; \ + picture->dest[2] += 8 * picture->pitches[2]; \ + } while (0); \ + picture->v_offset += 16; \ + if (picture->v_offset > picture->limit_y) { \ + if (mpeg2_cpu_state_restore) \ + mpeg2_cpu_state_restore (&cpu_state); \ + return; \ + } \ + picture->offset = 0; \ + } \ +} while (0) + +static inline int slice_init (picture_t * picture, int code) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int offset, height; + struct vo_frame_s * forward_reference_frame; + struct vo_frame_s * backward_reference_frame; + const MBAtab * mba; + + offset = picture->picture_structure == BOTTOM_FIELD; + picture->pitches[0] = picture->current_frame->pitches[0]; + picture->pitches[1] = picture->current_frame->pitches[1]; + picture->pitches[2] = picture->current_frame->pitches[2]; + + if( picture->forward_reference_frame ) { + forward_reference_frame = picture->forward_reference_frame; + } + else { + /* return 1; */ + forward_reference_frame = picture->current_frame; + } + + if( picture->backward_reference_frame ) { + backward_reference_frame = picture->backward_reference_frame; + } + else { + /* return 1; */ + backward_reference_frame = picture->current_frame; + } + + picture->f_motion.ref[0][0] = + forward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); + picture->f_motion.ref[0][1] = + forward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); + picture->f_motion.ref[0][2] = + forward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); + + picture->b_motion.ref[0][0] = + backward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); + picture->b_motion.ref[0][1] = + backward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); + picture->b_motion.ref[0][2] = + backward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); + + if (picture->picture_structure != FRAME_PICTURE) { + uint8_t ** forward_ref; + int bottom_field; + + bottom_field = (picture->picture_structure == BOTTOM_FIELD); + picture->dmv_offset = bottom_field ? 1 : -1; + picture->f_motion.ref2[0] = picture->f_motion.ref[bottom_field]; + picture->f_motion.ref2[1] = picture->f_motion.ref[!bottom_field]; + picture->b_motion.ref2[0] = picture->b_motion.ref[bottom_field]; + picture->b_motion.ref2[1] = picture->b_motion.ref[!bottom_field]; + + forward_ref = forward_reference_frame->base; + if (picture->second_field && (picture->picture_coding_type != B_TYPE)) + forward_ref = picture->current_frame->base; + + picture->f_motion.ref[1][0] = forward_ref[0] + (bottom_field ? 0 : picture->pitches[0]); + picture->f_motion.ref[1][1] = forward_ref[1] + (bottom_field ? 0 : picture->pitches[1]); + picture->f_motion.ref[1][2] = forward_ref[2] + (bottom_field ? 0 : picture->pitches[2]); + + picture->b_motion.ref[1][0] = + backward_reference_frame->base[0] + (bottom_field ? 0 : picture->pitches[0]); + picture->b_motion.ref[1][1] = + backward_reference_frame->base[1] + (bottom_field ? 0 : picture->pitches[1]); + picture->b_motion.ref[1][2] = + backward_reference_frame->base[2] + (bottom_field ? 0 : picture->pitches[2]); + } + + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; + picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; + picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; + + picture->v_offset = (code - 1) * 16; + offset = (code - 1); + if (picture->picture_structure != FRAME_PICTURE) + offset = 2 * offset; + + picture->dest[0] = picture->current_frame->base[0] + picture->pitches[0] * offset * 16; + picture->dest[1] = picture->current_frame->base[1] + picture->pitches[1] * offset * 8; + picture->dest[2] = picture->current_frame->base[2] + picture->pitches[2] * offset * 8; + + height = picture->coded_picture_height; + switch (picture->picture_structure) { + case BOTTOM_FIELD: + picture->dest[0] += picture->pitches[0]; + picture->dest[1] += picture->pitches[1]; + picture->dest[2] += picture->pitches[2]; + /* follow thru */ + case TOP_FIELD: + picture->pitches[0] <<= 1; + picture->pitches[1] <<= 1; + picture->pitches[2] <<= 1; + height >>= 1; + } + picture->limit_x = 2 * picture->coded_picture_width - 32; + picture->limit_y_16 = 2 * height - 32; + picture->limit_y_8 = 2 * height - 16; + picture->limit_y = height - 16; + + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); + + picture->quantizer_scale = get_quantizer_scale (picture); + + /* ignore intra_slice and all the extra data */ + while (bit_buf & 0x80000000) { + DUMPBITS (bit_buf, bits, 9); + NEEDBITS (bit_buf, bits, bit_ptr); + } + + /* decode initial macroblock address increment */ + offset = 0; + while (1) { + if (bit_buf >= 0x08000000) { + mba = MBA_5 + (UBITS (bit_buf, 6) - 2); + break; + } else if (bit_buf >= 0x01800000) { + mba = MBA_11 + (UBITS (bit_buf, 12) - 24); + break; + } else switch (UBITS (bit_buf, 12)) { + case 8: /* macroblock_escape */ + offset += 33; + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + case 15: /* macroblock_stuffing (MPEG1 only) */ + bit_buf &= 0xfffff; + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + default: /* error */ + return 1; + } + } + DUMPBITS (bit_buf, bits, mba->len + 1); + picture->offset = (offset + mba->mba) << 4; + + while (picture->offset - picture->coded_picture_width >= 0) { + picture->offset -= picture->coded_picture_width; + if ((picture->current_frame->proc_slice == NULL) || + (picture->picture_coding_type != B_TYPE)) { + picture->dest[0] += 16 * picture->pitches[0]; + picture->dest[1] += 8 * picture->pitches[1]; + picture->dest[2] += 8 * picture->pitches[2]; + } + picture->v_offset += 16; + } + if (picture->v_offset > picture->limit_y) + return 1; + + return 0; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + cpu_state_t cpu_state; + + bitstream_init (picture, buffer); + + if (slice_init (picture, code)) + return; + + if (mpeg2_cpu_state_save) + mpeg2_cpu_state_save (&cpu_state); + + while (1) { + int macroblock_modes; + int mba_inc; + const MBAtab * mba; + + NEEDBITS (bit_buf, bits, bit_ptr); + + macroblock_modes = get_macroblock_modes (picture); + + /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */ + if (macroblock_modes & MACROBLOCK_QUANT) + picture->quantizer_scale = get_quantizer_scale (picture); + + if (macroblock_modes & MACROBLOCK_INTRA) { + + int DCT_offset, DCT_stride; + int offset; + uint8_t * dest_y; + + if (picture->concealment_motion_vectors) { + if (picture->picture_structure == FRAME_PICTURE) + motion_fr_conceal (picture); + else + motion_fi_conceal (picture); + } else { + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; + picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; + picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; + } + + if (macroblock_modes & DCT_TYPE_INTERLACED) { + DCT_offset = picture->pitches[0]; + DCT_stride = picture->pitches[0] * 2; + } else { + DCT_offset = picture->pitches[0] * 8; + DCT_stride = picture->pitches[0]; + } + + offset = picture->offset; + dest_y = picture->dest[0] + offset; + slice_intra_DCT (picture, 0, dest_y, DCT_stride); + slice_intra_DCT (picture, 0, dest_y + 8, DCT_stride); + slice_intra_DCT (picture, 0, dest_y + DCT_offset, DCT_stride); + slice_intra_DCT (picture, 0, dest_y + DCT_offset + 8, DCT_stride); + slice_intra_DCT (picture, 1, picture->dest[1] + (offset >> 1), + picture->pitches[1]); + slice_intra_DCT (picture, 2, picture->dest[2] + (offset >> 1), + picture->pitches[2]); + + if (picture->picture_coding_type == D_TYPE) { + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); + } + } else { + + if (picture->picture_structure == FRAME_PICTURE) + switch (macroblock_modes & MOTION_TYPE_MASK) { + case MC_FRAME: + if (picture->mpeg1) + MOTION_CALL (motion_mp1, macroblock_modes); + else + MOTION_CALL (motion_fr_frame, macroblock_modes); + break; + + case MC_FIELD: + MOTION_CALL (motion_fr_field, macroblock_modes); + break; + + case MC_DMV: + MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); + break; + + case 0: + /* non-intra mb without forward mv in a P picture */ + picture->f_motion.pmv[0][0] = 0; + picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = 0; + picture->f_motion.pmv[1][1] = 0; + MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + break; + } + else + switch (macroblock_modes & MOTION_TYPE_MASK) { + case MC_FIELD: + MOTION_CALL (motion_fi_field, macroblock_modes); + break; + + case MC_16X8: + MOTION_CALL (motion_fi_16x8, macroblock_modes); + break; + + case MC_DMV: + MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); + break; + + case 0: + /* non-intra mb without forward mv in a P picture */ + picture->f_motion.pmv[0][0] = 0; + picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = 0; + picture->f_motion.pmv[1][1] = 0; + MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + break; + } + + if (macroblock_modes & MACROBLOCK_PATTERN) { + int coded_block_pattern; + int DCT_offset, DCT_stride; + int offset; + uint8_t * dest_y; + + if (macroblock_modes & DCT_TYPE_INTERLACED) { + DCT_offset = picture->pitches[0]; + DCT_stride = picture->pitches[0] * 2; + } else { + DCT_offset = picture->pitches[0] * 8; + DCT_stride = picture->pitches[0]; + } + + coded_block_pattern = get_coded_block_pattern (picture); + + offset = picture->offset; + dest_y = picture->dest[0] + offset; + if (coded_block_pattern & 0x20) + slice_non_intra_DCT (picture, dest_y, DCT_stride); + if (coded_block_pattern & 0x10) + slice_non_intra_DCT (picture, dest_y + 8, DCT_stride); + if (coded_block_pattern & 0x08) + slice_non_intra_DCT (picture, dest_y + DCT_offset, + DCT_stride); + if (coded_block_pattern & 0x04) + slice_non_intra_DCT (picture, dest_y + DCT_offset + 8, + DCT_stride); + if (coded_block_pattern & 0x2) + slice_non_intra_DCT (picture, + picture->dest[1] + (offset >> 1), + picture->pitches[1]); + if (coded_block_pattern & 0x1) + slice_non_intra_DCT (picture, + picture->dest[2] + (offset >> 1), + picture->pitches[2]); + } + + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; + } + + NEXT_MACROBLOCK; + + NEEDBITS (bit_buf, bits, bit_ptr); + mba_inc = 0; + while (1) { + if (bit_buf >= 0x10000000) { + mba = MBA_5 + (UBITS (bit_buf, 5) - 2); + break; + } else if (bit_buf >= 0x03000000) { + mba = MBA_11 + (UBITS (bit_buf, 11) - 24); + break; + } else switch (UBITS (bit_buf, 11)) { + case 8: /* macroblock_escape */ + mba_inc += 33; + /* pass through */ + case 15: /* macroblock_stuffing (MPEG1 only) */ + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + default: /* end of slice, or error */ + if (mpeg2_cpu_state_restore) + mpeg2_cpu_state_restore (&cpu_state); + return; + } + } + DUMPBITS (bit_buf, bits, mba->len); + mba_inc += mba->mba; + + if (mba_inc) { + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; + + if (picture->picture_coding_type == P_TYPE) { + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; + + do { + MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + NEXT_MACROBLOCK; + } while (--mba_inc); + } else { + do { + MOTION_CALL (motion_reuse, macroblock_modes); + NEXT_MACROBLOCK; + } while (--mba_inc); + } + } + } +#undef bit_buf +#undef bits +#undef bit_ptr +} diff --git a/src/video_dec/libmpeg2/slice_xvmc.c b/src/video_dec/libmpeg2/slice_xvmc.c new file mode 100644 index 000000000..014ae7924 --- /dev/null +++ b/src/video_dec/libmpeg2/slice_xvmc.c @@ -0,0 +1,1988 @@ +/* + * slice_xvmc.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include /* memcpy/memset, try to remove */ +#include +#include + +#include +#include +#include "mpeg2_internal.h" +#include + +#include +#include "accel_xvmc.h" +#include "xvmc.h" + + +#define MOTION_ACCEL XINE_VO_MOTION_ACCEL +#define IDCT_ACCEL XINE_VO_IDCT_ACCEL +#define SIGNED_INTRA XINE_VO_SIGNED_INTRA +#define ACCEL (MOTION_ACCEL | IDCT_ACCEL) + +#include "vlc.h" +/* original (non-patched) scan tables */ + +static const uint8_t mpeg2_scan_norm_orig[64] ATTR_ALIGN(16) = +{ + /* Zig-Zag scan pattern */ + 0, 1, 8,16, 9, 2, 3,10, + 17,24,32,25,18,11, 4, 5, + 12,19,26,33,40,48,41,34, + 27,20,13, 6, 7,14,21,28, + 35,42,49,56,57,50,43,36, + 29,22,15,23,30,37,44,51, + 58,59,52,45,38,31,39,46, + 53,60,61,54,47,55,62,63 +}; + +static const uint8_t mpeg2_scan_alt_orig[64] ATTR_ALIGN(16) = +{ + /* Alternate scan pattern */ + 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, + 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, + 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, + 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 +}; + +static uint8_t mpeg2_scan_alt_ptable[64] ATTR_ALIGN(16); +static uint8_t mpeg2_scan_norm_ptable[64] ATTR_ALIGN(16); +static uint8_t mpeg2_scan_orig_ptable[64] ATTR_ALIGN(16); + +void xvmc_setup_scan_ptable( void ) +{ + int i; + for (i=0; i<64; ++i) { + mpeg2_scan_norm_ptable[mpeg2_scan_norm_orig[i]] = mpeg2_scan_norm[i]; + mpeg2_scan_alt_ptable[mpeg2_scan_alt_orig[i]] = mpeg2_scan_alt[i]; + mpeg2_scan_orig_ptable[i] = i; + } +} + + +static const int non_linear_quantizer_scale [] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 18, 20, 22, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 104, 112 +}; + +static inline int get_xvmc_macroblock_modes (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int macroblock_modes; + const MBtab * tab; + + switch (picture->picture_coding_type) { + case I_TYPE: + + tab = MB_I + UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if ((! (picture->frame_pred_frame_dct)) && + (picture->picture_structure == FRAME_PICTURE)) { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + + return macroblock_modes; + + case P_TYPE: + + tab = MB_P + UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (picture->picture_structure != FRAME_PICTURE) { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } else if (picture->frame_pred_frame_dct) { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } else { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case B_TYPE: + + tab = MB_B + UBITS (bit_buf, 6); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (picture->picture_structure != FRAME_PICTURE) { + if (! (macroblock_modes & MACROBLOCK_INTRA)) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } else if (picture->frame_pred_frame_dct) { + /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } else { + if (macroblock_modes & MACROBLOCK_INTRA) + goto intra; + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { + intra: + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case D_TYPE: + + DUMPBITS (bit_buf, bits, 1); + return MACROBLOCK_INTRA; + + default: + return 0; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_xvmc_quantizer_scale (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + int quantizer_scale_code; + + quantizer_scale_code = UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, 5); + + if (picture->q_scale_type) + return non_linear_quantizer_scale [quantizer_scale_code]; + else + return quantizer_scale_code << 1; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_xvmc_motion_delta (picture_t * picture, int f_code) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + int delta; + int sign; + const MVtab * tab; + + if (bit_buf & 0x80000000) { + DUMPBITS (bit_buf, bits, 1); + return 0; + } else if (bit_buf >= 0x0c000000) { + + tab = MV_4 + UBITS (bit_buf, 4); + delta = (tab->delta << f_code) + 1; + bits += tab->len + f_code + 1; + bit_buf <<= tab->len; + + sign = SBITS (bit_buf, 1); + bit_buf <<= 1; + + if (f_code) + delta += UBITS (bit_buf, f_code); + bit_buf <<= f_code; + + return (delta ^ sign) - sign; + + } else { + + tab = MV_10 + UBITS (bit_buf, 10); + delta = (tab->delta << f_code) + 1; + bits += tab->len + 1; + bit_buf <<= tab->len; + + sign = SBITS (bit_buf, 1); + bit_buf <<= 1; + + if (f_code) { + NEEDBITS (bit_buf, bits, bit_ptr); + delta += UBITS (bit_buf, f_code); + DUMPBITS (bit_buf, bits, f_code); + } + + return (delta ^ sign) - sign; + + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int bound_motion_vector (int vec, int f_code) +{ +#if 1 + unsigned int limit; + int sign; + + limit = 16 << f_code; + + if ((unsigned int)(vec + limit) < 2 * limit) + return vec; + else { + sign = ((int32_t)vec) >> 31; + return vec - ((2 * limit) ^ sign) + sign; + } +#else + return ((int32_t)vec << (27 - f_code)) >> (27 - f_code); +#endif +} + +static inline int get_xvmc_dmv (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + const DMVtab * tab; + + tab = DMV_2 + UBITS (bit_buf, 2); + DUMPBITS (bit_buf, bits, tab->len); + return tab->dmv; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_xvmc_coded_block_pattern (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + + const CBPtab * tab; + + NEEDBITS (bit_buf, bits, bit_ptr); + + if (bit_buf >= 0x20000000) { + + tab = CBP_7 + (UBITS (bit_buf, 7) - 16); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + + } else { + + tab = CBP_9 + UBITS (bit_buf, 9); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + } + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_xvmc_luma_dc_dct_diff (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + const DCtab * tab; + int size; + int dc_diff; + + if (bit_buf < 0xf8000000) { + tab = DC_lum_5 + UBITS (bit_buf, 5); + size = tab->size; + if (size) { + bits += tab->len + size; + bit_buf <<= tab->len; + dc_diff = + UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + bit_buf <<= size; + return dc_diff; + } else { + DUMPBITS (bit_buf, bits, 3); + return 0; + } + } else { + tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len); + NEEDBITS (bit_buf, bits, bit_ptr); + dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + DUMPBITS (bit_buf, bits, size); + return dc_diff; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_xvmc_chroma_dc_dct_diff (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + const DCtab * tab; + int size; + int dc_diff; + + if (bit_buf < 0xf8000000) { + tab = DC_chrom_5 + UBITS (bit_buf, 5); + size = tab->size; + if (size) { + bits += tab->len + size; + bit_buf <<= tab->len; + dc_diff = + UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + bit_buf <<= size; + return dc_diff; + } else { + DUMPBITS (bit_buf, bits, 2); + return 0; + } + } else { + tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len + 1); + NEEDBITS (bit_buf, bits, bit_ptr); + dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + DUMPBITS (bit_buf, bits, size); + return dc_diff; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +#define SATURATE(val) \ +do { \ + if ((uint32_t)(val + 2048) > 4095) \ + val = (val > 0) ? 2047 : -2048; \ +} while (0) + +static void get_xvmc_intra_block_B14 (picture_t * picture) +{ + int i; + int j; + int l; + int val; + const uint8_t * scan = picture->scan; + uint8_t * scan_ptable = mpeg2_scan_orig_ptable; + uint8_t * quant_matrix = picture->intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + dest = picture->mc->blockptr; + + if( picture->mc->xvmc_accel & IDCT_ACCEL ) { + if ( scan == mpeg2_scan_norm ) { + scan = mpeg2_scan_norm_orig; + scan_ptable = mpeg2_scan_norm_ptable; + } else { + scan = mpeg2_scan_alt_orig; + scan_ptable = mpeg2_scan_alt_ptable; + } + } + + i = 0; + mismatch = ~dest[0]; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + l = scan_ptable[j = scan[i]]; + + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + l = scan_ptable[j = scan[i]]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = (SBITS (bit_buf, 12) * + quantizer_scale * quant_matrix[l]) / 16; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_xvmc_intra_block_B15 (picture_t * picture) +{ + int i; + int j; + int l; + int val; + const uint8_t * scan = picture->scan; + uint8_t * scan_ptable = mpeg2_scan_orig_ptable; + uint8_t * quant_matrix = picture->intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + dest = picture->mc->blockptr; + + if( picture->mc->xvmc_accel & IDCT_ACCEL ) { + if ( scan == mpeg2_scan_norm ) { + scan = mpeg2_scan_norm_orig; + scan_ptable = mpeg2_scan_norm_ptable; + } else { + scan = mpeg2_scan_alt_orig; + scan_ptable = mpeg2_scan_alt_ptable; + } + } + + i = 0; + mismatch = ~dest[0]; + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x04000000) { + + tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) { + + normal_code: + l = scan_ptable[j = scan[i]]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else { + + /* end of block. I commented out this code because if we */ + /* dont exit here we will still exit at the later test :) */ + + /* if (i >= 128) break; */ /* end of block */ + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check against buffer overflow */ + + l = scan_ptable[j = scan[i]]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = (SBITS (bit_buf, 12) * + quantizer_scale * quant_matrix[l]) / 16; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + } else if (bit_buf >= 0x02000000) { + tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_xvmc_non_intra_block (picture_t * picture) +{ + int i; + int j; + int l; + int val; + const uint8_t * scan = picture->scan; + uint8_t * scan_ptable = mpeg2_scan_orig_ptable; + uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + i = -1; + mismatch = 1; + + dest = picture->mc->blockptr; + + if( picture->mc->xvmc_accel & IDCT_ACCEL ) { + if ( scan == mpeg2_scan_norm ) { + scan = mpeg2_scan_norm_orig; + scan_ptable = mpeg2_scan_norm_ptable; + } else { + scan = mpeg2_scan_alt_orig; + scan_ptable = mpeg2_scan_alt_ptable; + } + } + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + if (bit_buf >= 0x28000000) { + tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); + goto entry_1; + } else + goto entry_2; + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + l = scan_ptable[j = scan[i]]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = ((2*tab->level+1) * quantizer_scale * quant_matrix[l]) >> 5; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + + entry_2: + if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + l = scan_ptable[j = scan[i]]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; + val = (val * quantizer_scale * quant_matrix[l]) / 32; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_xvmc_mpeg1_intra_block (picture_t * picture) +{ + int i; + int j; + int l; + int val; + const uint8_t * scan = picture->scan; + uint8_t * scan_ptable = mpeg2_scan_orig_ptable; + uint8_t * quant_matrix = picture->intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + i = 0; + + dest = picture->mc->blockptr; + + if( picture->mc->xvmc_accel & IDCT_ACCEL ) { + if ( scan == mpeg2_scan_norm ) { + scan = mpeg2_scan_norm_orig; + scan_ptable = mpeg2_scan_norm_ptable; + } else { + scan = mpeg2_scan_alt_orig; + scan_ptable = mpeg2_scan_alt_ptable; + } + } + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + l = scan_ptable[j = scan[i]]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; + + /* oddification */ + val = (val - 1) | 1; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + l = scan_ptable[j = scan[i]]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = SBITS (bit_buf, 8); + if (! (val & 0x7f)) { + DUMPBITS (bit_buf, bits, 8); + val = UBITS (bit_buf, 8) + 2 * val; + } + val = (val * quantizer_scale * quant_matrix[l]) / 16; + + /* oddification */ + val = (val + ~SBITS (val, 1)) | 1; + + SATURATE (val); + dest[j] = val; + + DUMPBITS (bit_buf, bits, 8); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static void get_xvmc_mpeg1_non_intra_block (picture_t * picture) +{ + int i; + int j; + int l; + int val; + const uint8_t * scan = picture->scan; + uint8_t * scan_ptable = mpeg2_scan_orig_ptable; + uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; + int quantizer_scale = picture->quantizer_scale; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + uint8_t * bit_ptr; + int16_t * dest; + + i = -1; + + dest = picture->mc->blockptr; + + if( picture->mc->xvmc_accel & IDCT_ACCEL ) { + if ( scan == mpeg2_scan_norm ) { + scan = mpeg2_scan_norm_orig; + scan_ptable = mpeg2_scan_norm_ptable; + } else { + scan = mpeg2_scan_alt_orig; + scan_ptable = mpeg2_scan_alt_ptable; + } + } + + bit_buf = picture->bitstream_buf; + bits = picture->bitstream_bits; + bit_ptr = picture->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + if (bit_buf >= 0x28000000) { + tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); + goto entry_1; + } else + goto entry_2; + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + l = scan_ptable[j = scan[i]]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = ((2*tab->level+1) * quantizer_scale * quant_matrix[l]) >> 5; + + /* oddification */ + val = (val - 1) | 1; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + + entry_2: + if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + l = scan_ptable[j = scan[i]]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = SBITS (bit_buf, 8); + if (! (val & 0x7f)) { + DUMPBITS (bit_buf, bits, 8); + val = UBITS (bit_buf, 8) + 2 * val; + } + val = 2 * (val + SBITS (val, 1)) + 1; + val = (val * quantizer_scale * quant_matrix[l]) / 32; + + /* oddification */ + val = (val + ~SBITS (val, 1)) | 1; + + SATURATE (val); + dest[j] = val; + + DUMPBITS (bit_buf, bits, 8); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + picture->bitstream_buf = bit_buf; + picture->bitstream_bits = bits; + picture->bitstream_ptr = bit_ptr; +} + +static inline void slice_xvmc_intra_DCT (picture_t * picture, int cc, + uint8_t * dest, int stride) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + NEEDBITS (bit_buf, bits, bit_ptr); + /* Get the intra DC coefficient and inverse quantize it */ + + // printf("slice: slice_xvmc_intra_DCT cc=%d pred[0]=%d\n",cc,picture->dc_dct_pred[0]); + if (cc == 0) + picture->dc_dct_pred[0] += get_xvmc_luma_dc_dct_diff (picture); + else + picture->dc_dct_pred[cc] += get_xvmc_chroma_dc_dct_diff (picture); + //TODO conversion to signed format + // printf("slice: pred[0]=%d presision=%d\n",picture->dc_dct_pred[0], + // picture->intra_dc_precision); + + mpeg2_zero_block(picture->mc->blockptr); + + picture->mc->blockptr[0] = picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision); + + if (picture->mpeg1) { + if (picture->picture_coding_type != D_TYPE) + get_xvmc_mpeg1_intra_block (picture); + } else if (picture->intra_vlc_format) + get_xvmc_intra_block_B15 (picture); + else + get_xvmc_intra_block_B14 (picture); + + if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL) { + //motion_comp only no idct acceleration so do it in software + mpeg2_idct (picture->mc->blockptr); + } + picture->mc->blockptr += 64; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline void slice_xvmc_non_intra_DCT (picture_t * picture, uint8_t * dest, + int stride) +{ + mpeg2_zero_block(picture->mc->blockptr); + + if (picture->mpeg1) + get_xvmc_mpeg1_non_intra_block (picture); + else + get_xvmc_non_intra_block (picture); + + if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL) { + // motion comp only no idct acceleration so do it in sw + mpeg2_idct (picture->mc->blockptr); + } + picture->mc->blockptr += 64; +} + +static void motion_mp1 (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = (motion->pmv[0][0] + + (get_xvmc_motion_delta (picture, + motion->f_code[0]) << motion->f_code[1])); + motion_x = bound_motion_vector (motion_x, + motion->f_code[0] + motion->f_code[1]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[0][1] + + (get_xvmc_motion_delta (picture, + motion->f_code[0]) << motion->f_code[1])); + motion_y = bound_motion_vector (motion_y, + motion->f_code[0] + motion->f_code[1]); + motion->pmv[0][1] = motion_y; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_frame (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_field (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int), + int dir) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y, field; + // unsigned int pos_x, pos_y, xy_half; + + NEEDBITS (bit_buf, bits, bit_ptr); + field = UBITS (bit_buf, 1); + picture->XvMC_mv_field_sel[0][dir] = field; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[0][1] >> 1) + get_xvmc_motion_delta (picture, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[0][1] = motion_y << 1; + + NEEDBITS (bit_buf, bits, bit_ptr); + field = UBITS (bit_buf, 1); + //TODO look at field select need bob (weave ok) + picture->XvMC_mv_field_sel[1][dir] = field; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[1][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[1][1] >> 1) + get_xvmc_motion_delta (picture, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[1][1] = motion_y << 1; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_dmv (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + + // TODO field select ?? possible need to be 0 + picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + NEEDBITS (bit_buf, bits, bit_ptr); + + motion_y = (motion->pmv[0][1] >> 1) + get_xvmc_motion_delta (picture, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_reuse (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ + int motion_x, motion_y; + + motion_x = motion->pmv[0][0]; + motion_y = motion->pmv[0][1]; + +} + +/* like motion_frame, but parsing without actual motion compensation */ +static void motion_fr_conceal (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (picture->f_motion.pmv[0][0] + + get_xvmc_motion_delta (picture, picture->f_motion.f_code[0])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (picture->f_motion.pmv[0][1] + + get_xvmc_motion_delta (picture, picture->f_motion.f_code[1])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); + picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; + + DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_field (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + uint8_t ** ref_field; + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + + // TODO field select may need to do something here for bob (weave ok) + picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; + + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_16x8 (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + uint8_t ** ref_field; + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + + // TODO field select may need to do something here bob (weave ok) + picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; + + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[0][1] = motion_y; + + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + + // TODO field select may need to do something here for bob (weave ok) + picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; + + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[1][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[1][1] + get_xvmc_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion_y; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_dmv (picture_t * picture, motion_t * motion, + void (** table) (uint8_t *, uint8_t *, int, int)) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int motion_x, motion_y; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + NEEDBITS (bit_buf, bits, bit_ptr); + + motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + + // TODO field select may need to do something here for bob (weave ok) + picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; + +#undef bit_buf +#undef bits +#undef bit_ptr +} + + +static void motion_fi_conceal (picture_t * picture) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); /* remove field_select */ + + tmp = (picture->f_motion.pmv[0][0] + + get_xvmc_motion_delta (picture, picture->f_motion.f_code[0])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (picture->f_motion.pmv[0][1] + + get_xvmc_motion_delta (picture, picture->f_motion.f_code[1])); + tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); + picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; + + DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ +#undef bit_buf +#undef bits +#undef bit_ptr +} + +#define MOTION_CALL(routine,direction) \ +do { \ + if ((direction) & MACROBLOCK_MOTION_FORWARD) \ + routine (picture, &(picture->f_motion), mpeg2_mc.put); \ + if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ + routine (picture, &(picture->b_motion), \ + ((direction) & MACROBLOCK_MOTION_FORWARD ? \ + mpeg2_mc.avg : mpeg2_mc.put)); \ +} while (0) + +#define NEXT_MACROBLOCK \ +do { \ + picture->offset += 16; \ + if (picture->offset == picture->coded_picture_width) { \ + do { /* just so we can use the break statement */ \ + if (picture->current_frame->proc_slice) { \ + picture->current_frame->proc_slice (picture->current_frame, \ + picture->dest); \ + if (picture->picture_coding_type == B_TYPE) \ + break; \ + } \ + picture->dest[0] += 16 * picture->pitches[0]; \ + picture->dest[1] += 8 * picture->pitches[1]; \ + picture->dest[2] += 8 * picture->pitches[2]; \ + } while (0); \ + picture->v_offset += 16; \ + if (picture->v_offset > picture->limit_y) { \ + if (mpeg2_cpu_state_restore) \ + mpeg2_cpu_state_restore (&cpu_state); \ + return; \ + } \ + picture->offset = 0; \ + } \ +} while (0) + +static inline int slice_xvmc_init (picture_t * picture, int code) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + int offset, height; + struct vo_frame_s * forward_reference_frame; + struct vo_frame_s * backward_reference_frame; + const MBAtab * mba; + + offset = picture->picture_structure == BOTTOM_FIELD; + picture->pitches[0] = picture->current_frame->pitches[0]; + picture->pitches[1] = picture->current_frame->pitches[1]; + picture->pitches[2] = picture->current_frame->pitches[2]; + + if( picture->forward_reference_frame ) { + forward_reference_frame = picture->forward_reference_frame; + } + else { + /* return 1; */ + forward_reference_frame = picture->current_frame; + } + + if( picture->backward_reference_frame ) { + backward_reference_frame = picture->backward_reference_frame; + } + else { + /* return 1; */ + backward_reference_frame = picture->current_frame; + } + + picture->f_motion.ref[0][0] = + forward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); + picture->f_motion.ref[0][1] = + forward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); + picture->f_motion.ref[0][2] = + forward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); + + picture->b_motion.ref[0][0] = + backward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); + picture->b_motion.ref[0][1] = + backward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); + picture->b_motion.ref[0][2] = + backward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); + + if (picture->picture_structure != FRAME_PICTURE) { + uint8_t ** forward_ref; + int bottom_field; + + bottom_field = (picture->picture_structure == BOTTOM_FIELD); + picture->dmv_offset = bottom_field ? 1 : -1; + picture->f_motion.ref2[0] = picture->f_motion.ref[bottom_field]; + picture->f_motion.ref2[1] = picture->f_motion.ref[!bottom_field]; + picture->b_motion.ref2[0] = picture->b_motion.ref[bottom_field]; + picture->b_motion.ref2[1] = picture->b_motion.ref[!bottom_field]; + + forward_ref = forward_reference_frame->base; + if (picture->second_field && (picture->picture_coding_type != B_TYPE)) + forward_ref = picture->current_frame->base; + + picture->f_motion.ref[1][0] = forward_ref[0] + (bottom_field ? 0 : picture->pitches[0]); + picture->f_motion.ref[1][1] = forward_ref[1] + (bottom_field ? 0 : picture->pitches[1]); + picture->f_motion.ref[1][2] = forward_ref[2] + (bottom_field ? 0 : picture->pitches[2]); + + picture->b_motion.ref[1][0] = + backward_reference_frame->base[0] + (bottom_field ? 0 : picture->pitches[0]); + picture->b_motion.ref[1][1] = + backward_reference_frame->base[1] + (bottom_field ? 0 : picture->pitches[1]); + picture->b_motion.ref[1][2] = + backward_reference_frame->base[2] + (bottom_field ? 0 : picture->pitches[2]); + } + + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; + picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; + picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; + + picture->v_offset = (code - 1) * 16; + offset = (code - 1); + if (picture->current_frame->proc_slice && picture->picture_coding_type == B_TYPE) + offset = 0; + else if (picture->picture_structure != FRAME_PICTURE) + offset = 2 * offset; + + picture->dest[0] = picture->current_frame->base[0] + picture->pitches[0] * offset * 16; + picture->dest[1] = picture->current_frame->base[1] + picture->pitches[1] * offset * 8; + picture->dest[2] = picture->current_frame->base[2] + picture->pitches[2] * offset * 8; + + height = picture->coded_picture_height; + switch (picture->picture_structure) { + case BOTTOM_FIELD: + picture->dest[0] += picture->pitches[0]; + picture->dest[1] += picture->pitches[1]; + picture->dest[2] += picture->pitches[2]; + /* follow thru */ + case TOP_FIELD: + picture->pitches[0] <<= 1; + picture->pitches[1] <<= 1; + picture->pitches[2] <<= 1; + height >>= 1; + } + picture->limit_x = 2 * picture->coded_picture_width - 32; + picture->limit_y_16 = 2 * height - 32; + picture->limit_y_8 = 2 * height - 16; + picture->limit_y = height - 16; + + //TODO conversion to signed format signed format + if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && + !(picture->mc->xvmc_accel & SIGNED_INTRA)) { + //Motion Comp only unsigned intra + // original: + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); + } else { + //Motion Comp only signed intra MOTION_ACCEL+SIGNED_INTRA + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 0; + } + + picture->quantizer_scale = get_xvmc_quantizer_scale (picture); + + /* ignore intra_slice and all the extra data */ + while (bit_buf & 0x80000000) { + DUMPBITS (bit_buf, bits, 9); + NEEDBITS (bit_buf, bits, bit_ptr); + } + + /* decode initial macroblock address increment */ + offset = 0; + while (1) { + if (bit_buf >= 0x08000000) { + mba = MBA_5 + (UBITS (bit_buf, 6) - 2); + break; + } else if (bit_buf >= 0x01800000) { + mba = MBA_11 + (UBITS (bit_buf, 12) - 24); + break; + } else switch (UBITS (bit_buf, 12)) { + case 8: /* macroblock_escape */ + offset += 33; + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + case 15: /* macroblock_stuffing (MPEG1 only) */ + bit_buf &= 0xfffff; + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + default: /* error */ + return 1; + } + } + DUMPBITS (bit_buf, bits, mba->len + 1); + picture->offset = (offset + mba->mba) << 4; + + while (picture->offset - picture->coded_picture_width >= 0) { + picture->offset -= picture->coded_picture_width; + if ((picture->current_frame->proc_slice == NULL) || + (picture->picture_coding_type != B_TYPE)) { + picture->dest[0] += 16 * picture->pitches[0]; + picture->dest[1] += 8 * picture->pitches[1]; + picture->dest[2] += 8 * picture->pitches[2]; + } + picture->v_offset += 16; + } + if (picture->v_offset > picture->limit_y) + return 1; + + return 0; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer) +{ +#define bit_buf (picture->bitstream_buf) +#define bits (picture->bitstream_bits) +#define bit_ptr (picture->bitstream_ptr) + cpu_state_t cpu_state; + xine_xvmc_t *xvmc = (xine_xvmc_t *) picture->current_frame->accel_data; + + if (1 == code) { + accel->xvmc_last_slice_code = 0; + } + if ((code != accel->xvmc_last_slice_code + 1) && + (code != accel->xvmc_last_slice_code)) + return; + + bitstream_init (picture, buffer); + + if (slice_xvmc_init (picture, code)) + return; + + if (mpeg2_cpu_state_save) + mpeg2_cpu_state_save (&cpu_state); + + while (1) { + int macroblock_modes; + int mba_inc; + const MBAtab * mba; + + NEEDBITS (bit_buf, bits, bit_ptr); + + macroblock_modes = get_xvmc_macroblock_modes (picture); //macroblock_modes() + picture->XvMC_mb_type = macroblock_modes & 0x1F; + picture->XvMC_dct_type = (macroblock_modes & DCT_TYPE_INTERLACED)>>5; + picture->XvMC_motion_type = (macroblock_modes & MOTION_TYPE_MASK)>>6; + + picture->XvMC_x = picture->offset/16; + picture->XvMC_y = picture->v_offset/16; + + if((picture->XvMC_x == 0) && (picture->XvMC_y == 0)) { + picture->XvMC_mv_field_sel[0][0] = + picture->XvMC_mv_field_sel[1][0] = + picture->XvMC_mv_field_sel[0][1] = + picture->XvMC_mv_field_sel[1][1] = 0; + } + + picture->XvMC_cbp = 0x3f; //TODO set for intra 4:2:0 6 blocks yyyyuv all enabled + + /* maybe integrate MACROBLOCK_QUANT test into get_xvmc_macroblock_modes ? */ + if (macroblock_modes & MACROBLOCK_QUANT) + picture->quantizer_scale = get_xvmc_quantizer_scale (picture); + if (macroblock_modes & MACROBLOCK_INTRA) { + + int DCT_offset, DCT_stride; + int offset; + uint8_t * dest_y; + + if (picture->concealment_motion_vectors) { + if (picture->picture_structure == FRAME_PICTURE) + motion_fr_conceal (picture); + else + motion_fi_conceal (picture); + } else { + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; + picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; + picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; + } + + if (macroblock_modes & DCT_TYPE_INTERLACED) { + DCT_offset = picture->pitches[0]; + DCT_stride = picture->pitches[0] * 2; + } else { + DCT_offset = picture->pitches[0] * 8; + DCT_stride = picture->pitches[0]; + } + offset = picture->offset; + dest_y = picture->dest[0] + offset; + // unravaled loop of 6 block(i) calls in macroblock() + slice_xvmc_intra_DCT (picture, 0, dest_y, DCT_stride); + slice_xvmc_intra_DCT (picture, 0, dest_y + 8, DCT_stride); + slice_xvmc_intra_DCT (picture, 0, dest_y + DCT_offset, DCT_stride); + slice_xvmc_intra_DCT (picture, 0, dest_y + DCT_offset + 8, DCT_stride); + slice_xvmc_intra_DCT (picture, 1, picture->dest[1] + (offset >> 1), + picture->pitches[1]); + slice_xvmc_intra_DCT (picture, 2, picture->dest[2] + (offset >> 1), + picture->pitches[2]); + + if (picture->picture_coding_type == D_TYPE) { + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); + } + } else { + picture->XvMC_cbp = 0; + + if (picture->picture_structure == FRAME_PICTURE) + switch (macroblock_modes & MOTION_TYPE_MASK) { + case MC_FRAME: + if (picture->mpeg1) { + MOTION_CALL (motion_mp1, macroblock_modes); + } else { + MOTION_CALL (motion_fr_frame, macroblock_modes); + } + break; + + case MC_FIELD: + //MOTION_CALL (motion_fr_field, macroblock_modes); + + if ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD) + motion_fr_field(picture, &(picture->f_motion), + mpeg2_mc.put,0); + if ((macroblock_modes) & MACROBLOCK_MOTION_BACKWARD) + motion_fr_field(picture, &(picture->b_motion), + ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD ? + mpeg2_mc.avg : mpeg2_mc.put),1); + + break; + + case MC_DMV: + MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); + break; + + case 0: + /* non-intra mb without forward mv in a P picture */ + picture->f_motion.pmv[0][0] = 0; + picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = 0; + picture->f_motion.pmv[1][1] = 0; + // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + break; + } + else + switch (macroblock_modes & MOTION_TYPE_MASK) { + case MC_FIELD: + MOTION_CALL (motion_fi_field, macroblock_modes); + break; + + case MC_16X8: + MOTION_CALL (motion_fi_16x8, macroblock_modes); + break; + + case MC_DMV: + MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); + break; + + case 0: + /* non-intra mb without forward mv in a P picture */ + picture->f_motion.pmv[0][0] = 0; + picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = 0; + picture->f_motion.pmv[1][1] = 0; + // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + break; + } + + if (macroblock_modes & MACROBLOCK_PATTERN) { + int coded_block_pattern; + int DCT_offset, DCT_stride; + int offset; + uint8_t * dest_y; + + if (macroblock_modes & DCT_TYPE_INTERLACED) { + DCT_offset = picture->pitches[0]; + DCT_stride = picture->pitches[0] * 2; + } else { + DCT_offset = picture->pitches[0] * 8; + DCT_stride = picture->pitches[0]; + } + + picture->XvMC_cbp = coded_block_pattern = get_xvmc_coded_block_pattern (picture); + offset = picture->offset; + dest_y = picture->dest[0] + offset; + // TODO optimize not fully used for idct accel only mc. + if (coded_block_pattern & 0x20) + slice_xvmc_non_intra_DCT (picture, dest_y, DCT_stride); // cc0 luma 0 + if (coded_block_pattern & 0x10) + slice_xvmc_non_intra_DCT (picture, dest_y + 8, DCT_stride); // cc0 luma 1 + if (coded_block_pattern & 0x08) + slice_xvmc_non_intra_DCT (picture, dest_y + DCT_offset, + DCT_stride); // cc0 luma 2 + if (coded_block_pattern & 0x04) + slice_xvmc_non_intra_DCT (picture, dest_y + DCT_offset + 8, + DCT_stride); // cc0 luma 3 + if (coded_block_pattern & 0x2) + slice_xvmc_non_intra_DCT (picture, + picture->dest[1] + (offset >> 1), + picture->pitches[1]); // cc1 croma + if (coded_block_pattern & 0x1) + slice_xvmc_non_intra_DCT (picture, + picture->dest[2] + (offset >> 1), + picture->pitches[2]); // cc2 croma + } + + if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && + !(picture->mc->xvmc_accel & SIGNED_INTRA)) { + // original: + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; + + } else { // MOTION_ACCEL+SIGNED_INTRA + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 0; + } + + } + xvmc->proc_macro_block(picture->XvMC_x, picture->XvMC_y, + picture->XvMC_mb_type, + picture->XvMC_motion_type, + picture->XvMC_mv_field_sel, + picture->XvMC_dmvector, + picture->XvMC_cbp, + picture->XvMC_dct_type, + picture->current_frame, + picture->forward_reference_frame, + picture->backward_reference_frame, + picture->picture_structure, + picture->second_field, + picture->f_motion.pmv, + picture->b_motion.pmv); + + + NEXT_MACROBLOCK; + + NEEDBITS (bit_buf, bits, bit_ptr); + mba_inc = 0; + while (1) { + if (bit_buf >= 0x10000000) { + mba = MBA_5 + (UBITS (bit_buf, 5) - 2); + break; + } else if (bit_buf >= 0x03000000) { + mba = MBA_11 + (UBITS (bit_buf, 11) - 24); + break; + } else switch (UBITS (bit_buf, 11)) { + case 8: /* macroblock_escape */ + mba_inc += 33; + /* pass through */ + case 15: /* macroblock_stuffing (MPEG1 only) */ + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + default: /* end of slice, or error */ + if (mpeg2_cpu_state_restore) + mpeg2_cpu_state_restore (&cpu_state); + accel->xvmc_last_slice_code = code; + return; + } + } + DUMPBITS (bit_buf, bits, mba->len); + mba_inc += mba->mba; + if (mba_inc) { + //TODO conversion to signed format signed format + if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && + !(picture->mc->xvmc_accel & SIGNED_INTRA)) { + // original: + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; + } else { // MOTION_ACCEL+SIGNED_INTRA + picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = + picture->dc_dct_pred[2] = 0; + } + + picture->XvMC_cbp = 0; + if (picture->picture_coding_type == P_TYPE) { + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; + picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; + + do { + if(picture->mc->xvmc_accel) { + + /* derive motion_type */ + if(picture->picture_structure == FRAME_PICTURE) { + picture->XvMC_motion_type = XINE_MC_FRAME; + } else { + picture->XvMC_motion_type = XINE_MC_FIELD; + /* predict from field of same parity */ + picture->XvMC_mv_field_sel[0][0] = + picture->XvMC_mv_field_sel[0][1] = + (picture->picture_structure==BOTTOM_FIELD); + } + picture->XvMC_mb_type = macroblock_modes & 0x1E; + picture->XvMC_x = picture->offset/16; + picture->XvMC_y = picture->v_offset/16; + + xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y, + picture->XvMC_mb_type, + picture->XvMC_motion_type, + picture->XvMC_mv_field_sel, + picture->XvMC_dmvector, + picture->XvMC_cbp, + picture->XvMC_dct_type, + picture->current_frame, + picture->forward_reference_frame, + picture->backward_reference_frame, + picture->picture_structure, + picture->second_field, + picture->f_motion.pmv, + picture->b_motion.pmv); + } else { + // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + } + NEXT_MACROBLOCK; + } while (--mba_inc); + } else { + do { + if(picture->mc->xvmc_accel) { + + /* derive motion_type */ + if(picture->picture_structure == FRAME_PICTURE) { + picture->XvMC_motion_type = XINE_MC_FRAME; + } else { + picture->XvMC_motion_type = XINE_MC_FIELD; + /* predict from field of same parity */ + picture->XvMC_mv_field_sel[0][0] = + picture->XvMC_mv_field_sel[0][1] = + (picture->picture_structure==BOTTOM_FIELD); + } + + picture->XvMC_mb_type = macroblock_modes & 0x1E; + picture->XvMC_x = picture->offset/16; + picture->XvMC_y = picture->v_offset/16; + + xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y, + picture->XvMC_mb_type, + picture->XvMC_motion_type, + picture->XvMC_mv_field_sel, + picture->XvMC_dmvector, + picture->XvMC_cbp, + picture->XvMC_dct_type, + picture->current_frame, + picture->forward_reference_frame, + picture->backward_reference_frame, + picture->picture_structure, + picture->second_field, + picture->f_motion.pmv, + picture->b_motion.pmv); + } else { + MOTION_CALL (motion_reuse, macroblock_modes); + } + NEXT_MACROBLOCK; + } while (--mba_inc); + } + } + } + accel->xvmc_last_slice_code = code; +#undef bit_buf +#undef bits +#undef bit_ptr +} + diff --git a/src/video_dec/libmpeg2/slice_xvmc_vld.c b/src/video_dec/libmpeg2/slice_xvmc_vld.c new file mode 100644 index 000000000..3606cf66b --- /dev/null +++ b/src/video_dec/libmpeg2/slice_xvmc_vld.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2004 The Unichrome project. All rights reserved. + * + * This program 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTIES OR REPRESENTATIONS; 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. + * + * + */ + +#include +#include +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "xvmc_vld.h" + +static const uint8_t zig_zag_scan[64] ATTR_ALIGN(16) = +{ + /* Zig-Zag scan pattern */ + 0, 1, 8,16, 9, 2, 3,10, + 17,24,32,25,18,11, 4, 5, + 12,19,26,33,40,48,41,34, + 27,20,13, 6, 7,14,21,28, + 35,42,49,56,57,50,43,36, + 29,22,15,23,30,37,44,51, + 58,59,52,45,38,31,39,46, + 53,60,61,54,47,55,62,63 +}; + +static const uint8_t alternate_scan [64] ATTR_ALIGN(16) = +{ + /* Alternate scan pattern */ + 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, + 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, + 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, + 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 +}; + +void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture, + int code, uint8_t *buffer, uint32_t chunk_size, + uint8_t *chunk_buffer) + +{ + vo_frame_t + *frame = picture->current_frame; + xine_xxmc_t + *xxmc = (xine_xxmc_t *) frame->accel_data; + xine_vld_frame_t + *vft = &xxmc->vld_frame; + unsigned + mb_frame_height; + int + i; + const uint8_t * + scan_pattern; + float + ms_per_slice; + + if (1 == code && accel->xvmc_last_slice_code != 1) { + frame->bad_frame = 1; + accel->slices_per_row = 1; + accel->row_slice_count = 1; + + /* + * Check that first field went through OK. Otherwise, + * indicate bad frame. + */ + + if (picture->second_field) { + accel->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1; + xxmc->decoded = 0; + } else { + accel->xvmc_last_slice_code = 0; + } + + mb_frame_height = + (!(picture->mpeg1) && (picture->progressive_sequence)) ? + 2*((picture->coded_picture_height+31) >> 5) : + (picture->coded_picture_height+15) >> 4; + accel->xxmc_mb_pic_height = (picture->picture_structure == FRAME_PICTURE ) ? + mb_frame_height : mb_frame_height >> 1; + + ms_per_slice = 1000. / (90000. * mb_frame_height) * frame->duration; + xxmc->sleep = 1. / (ms_per_slice * 0.45); + if (xxmc->sleep < 1.) xxmc->sleep = 1.; + + if (picture->mpeg1) { + vft->mv_ranges[0][0] = picture->b_motion.f_code[0]; + vft->mv_ranges[0][1] = picture->b_motion.f_code[0]; + vft->mv_ranges[1][0] = picture->f_motion.f_code[0]; + vft->mv_ranges[1][1] = picture->f_motion.f_code[0]; + } else { + vft->mv_ranges[0][0] = picture->b_motion.f_code[0]; + vft->mv_ranges[0][1] = picture->b_motion.f_code[1]; + vft->mv_ranges[1][0] = picture->f_motion.f_code[0]; + vft->mv_ranges[1][1] = picture->f_motion.f_code[1]; + } + + vft->picture_structure = picture->picture_structure; + vft->picture_coding_type = picture->picture_coding_type; + vft->mpeg_coding = (picture->mpeg1) ? 0 : 1; + vft->progressive_sequence = picture->progressive_sequence; + vft->scan = (picture->scan == mpeg2_scan_alt); + vft->pred_dct_frame = picture->frame_pred_frame_dct; + vft->concealment_motion_vectors = + picture->concealment_motion_vectors; + vft->q_scale_type = picture->q_scale_type; + vft->intra_vlc_format = picture->intra_vlc_format; + vft->intra_dc_precision = picture->intra_dc_precision; + vft->second_field = picture->second_field; + + /* + * Translation of libmpeg2's Q-matrix layout to VLD XvMC's. + * Errors here will give + * blocky artifacts and sometimes wrong colors. + */ + + scan_pattern = (vft->scan) ? alternate_scan : zig_zag_scan; + + if ((vft->load_intra_quantizer_matrix = picture->load_intra_quantizer_matrix)) { + for (i=0; i<64; ++i) { + vft->intra_quantizer_matrix[scan_pattern[i]] = + picture->intra_quantizer_matrix[picture->scan[i]]; + } + } + + if ((vft->load_non_intra_quantizer_matrix = picture->load_non_intra_quantizer_matrix)) { + for (i=0; i<64; ++i) { + vft->non_intra_quantizer_matrix[scan_pattern[i]] = + picture->non_intra_quantizer_matrix[picture->scan[i]]; + } + } + + picture->load_intra_quantizer_matrix = 0; + picture->load_non_intra_quantizer_matrix = 0; + vft->forward_reference_frame = picture->forward_reference_frame; + vft->backward_reference_frame = picture->backward_reference_frame; + xxmc->proc_xxmc_begin( frame ); + if (xxmc->result != 0) { + accel->xvmc_last_slice_code=-1; + } + } + + if (((code == accel->xvmc_last_slice_code + 1) || + (code == accel->xvmc_last_slice_code))) { + + /* + * Send this slice to the output plugin. May stall for a long + * time in proc_slice; + */ + + frame->bad_frame = 1; + xxmc->slice_data_size = chunk_size; + xxmc->slice_data = chunk_buffer; + xxmc->slice_code = code; + + xxmc->proc_xxmc_slice( frame ); + + if (xxmc->result != 0) { + accel->xvmc_last_slice_code=-1; + return; + } + /* + * Keep track of slices. + */ + + accel->row_slice_count = (accel->xvmc_last_slice_code == code) ? + accel->row_slice_count + 1 : 1; + accel->slices_per_row = (accel->row_slice_count > accel->slices_per_row) ? + accel->row_slice_count:accel->slices_per_row; + accel->xvmc_last_slice_code = code; + + } else { + + /* + * An error has occured. + */ + + lprintf("libmpeg2: VLD XvMC: Slice error.\n"); + accel->xvmc_last_slice_code = -1; + return; + } +} + +void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code) +{ + vo_frame_t + *frame = picture->current_frame; + xine_xxmc_t + *xxmc = (xine_xxmc_t *) frame->accel_data; + + if (xxmc->decoded) return; + if (accel->xvmc_last_slice_code == -1) { + xxmc->proc_xxmc_flush( frame ); + return; + } + + if ((code != 0xff) || ((accel->xvmc_last_slice_code == + accel->xxmc_mb_pic_height) && + accel->slices_per_row == accel->row_slice_count)) { + + xxmc->proc_xxmc_flush( frame ); + + if (xxmc->result) { + accel->xvmc_last_slice_code=-1; + frame->bad_frame = 1; + return; + } + xxmc->decoded = 1; + accel->xvmc_last_slice_code = 0; + if (picture->picture_structure == 3 || picture->second_field) { + if (xxmc->result == 0) + frame->bad_frame = 0; + } + } +} diff --git a/src/video_dec/libmpeg2/stats.c b/src/video_dec/libmpeg2/stats.c new file mode 100644 index 000000000..63c701179 --- /dev/null +++ b/src/video_dec/libmpeg2/stats.c @@ -0,0 +1,317 @@ +/* + * stats.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include +#include + +#include "mpeg2_internal.h" + +static int debug_level = -1; + +/* Determine is debug output is required. */ +/* We could potentially have multiple levels of debug info */ +static int debug_is_on (void) +{ + char * env_var; + + if (debug_level < 0) { + env_var = getenv ("MPEG2_DEBUG"); + + if (env_var) + debug_level = 1; + else + debug_level = 0; + } + + return debug_level; +} + +static void stats_picture (uint8_t * buffer) +{ + static const char *const picture_coding_type_str [8] = { + "Invalid picture type", + "I-type", + "P-type", + "B-type", + "D (very bad)", + "Invalid","Invalid","Invalid" + }; + + int picture_coding_type; + int temporal_reference; + int vbv_delay; + + temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6); + picture_coding_type = (buffer [1] >> 3) & 7; + vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) | + (buffer[3] >> 3)) & 0xffff; + + fprintf (stderr, " (picture) %s temporal_reference %d, vbv_delay %d\n", + picture_coding_type_str [picture_coding_type], + temporal_reference, vbv_delay); +} + +static void stats_user_data (uint8_t * buffer) +{ + fprintf (stderr, " (user_data)\n"); +} + +static void stats_sequence (uint8_t * buffer) +{ + static const char *const aspect_ratio_information_str[8] = { + "Invalid Aspect Ratio", + "1:1", + "4:3", + "16:9", + "2.21:1", + "Invalid Aspect Ratio", + "Invalid Aspect Ratio", + "Invalid Aspect Ratio" + }; + static const char *const frame_rate_str[16] = { + "Invalid frame_rate_code", + "23.976", "24", "25" , "29.97", + "30" , "50", "59.94", "60" , + "Invalid frame_rate_code", "Invalid frame_rate_code", + "Invalid frame_rate_code", "Invalid frame_rate_code", + "Invalid frame_rate_code", "Invalid frame_rate_code", + "Invalid frame_rate_code" + }; + + int horizontal_size; + int vertical_size; + int aspect_ratio_information; + int frame_rate_code; + int bit_rate_value; + int vbv_buffer_size_value; + int constrained_parameters_flag; + int load_intra_quantizer_matrix; + int load_non_intra_quantizer_matrix; + + vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; + horizontal_size = vertical_size >> 12; + vertical_size &= 0xfff; + aspect_ratio_information = buffer[3] >> 4; + frame_rate_code = buffer[3] & 15; + bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6); + vbv_buffer_size_value = ((buffer[6] << 5) | (buffer[7] >> 3)) & 0x3ff; + constrained_parameters_flag = buffer[7] & 4; + load_intra_quantizer_matrix = buffer[7] & 2; + if (load_intra_quantizer_matrix) + buffer += 64; + load_non_intra_quantizer_matrix = buffer[7] & 1; + + fprintf (stderr, " (seq) %dx%d %s, %s fps, %5.0f kbps, VBV %d kB%s%s%s\n", + horizontal_size, vertical_size, + aspect_ratio_information_str [aspect_ratio_information], + frame_rate_str [frame_rate_code], + bit_rate_value * 400.0 / 1000.0, + 2 * vbv_buffer_size_value, + constrained_parameters_flag ? " , CP":"", + load_intra_quantizer_matrix ? " , Custom Intra Matrix":"", + load_non_intra_quantizer_matrix ? " , Custom Non-Intra Matrix":""); +} + +static void stats_sequence_error (uint8_t * buffer) +{ + fprintf (stderr, " (sequence_error)\n"); +} + +static void stats_sequence_end (uint8_t * buffer) +{ + fprintf (stderr, " (sequence_end)\n"); +} + +static void stats_group (uint8_t * buffer) +{ + fprintf (stderr, " (group)%s%s\n", + (buffer[4] & 0x40) ? " closed_gop" : "", + (buffer[4] & 0x20) ? " broken_link" : ""); +} + +static void stats_slice (int code, uint8_t * buffer) +{ + /* fprintf (stderr, " (slice %d)\n", code); */ +} + +static void stats_sequence_extension (uint8_t * buffer) +{ + static const char *const chroma_format_str[4] = { + "Invalid Chroma Format", + "4:2:0 Chroma", + "4:2:2 Chroma", + "4:4:4 Chroma" + }; + + int progressive_sequence; + int chroma_format; + + progressive_sequence = (buffer[1] >> 3) & 1; + chroma_format = (buffer[1] >> 1) & 3; + + fprintf (stderr, " (seq_ext) progressive_sequence %d, %s\n", + progressive_sequence, chroma_format_str [chroma_format]); +} + +static void stats_sequence_display_extension (uint8_t * buffer) +{ + fprintf (stderr, " (sequence_display_extension)\n"); +} + +static void stats_quant_matrix_extension (uint8_t * buffer) +{ + fprintf (stderr, " (quant_matrix_extension)\n"); +} + +static void stats_copyright_extension (uint8_t * buffer) +{ + fprintf (stderr, " (copyright_extension)\n"); +} + + +static void stats_sequence_scalable_extension (uint8_t * buffer) +{ + fprintf (stderr, " (sequence_scalable_extension)\n"); +} + +static void stats_picture_display_extension (uint8_t * buffer) +{ + fprintf (stderr, " (picture_display_extension)\n"); +} + +static void stats_picture_coding_extension (uint8_t * buffer) +{ + static const char *const picture_structure_str[4] = { + "Invalid Picture Structure", + "Top field", + "Bottom field", + "Frame Picture" + }; + + int f_code[2][2]; + int intra_dc_precision; + int picture_structure; + int top_field_first; + int frame_pred_frame_dct; + int concealment_motion_vectors; + int q_scale_type; + int intra_vlc_format; + int alternate_scan; + int repeat_first_field; + int progressive_frame; + + f_code[0][0] = buffer[0] & 15; + f_code[0][1] = buffer[1] >> 4; + f_code[1][0] = buffer[1] & 15; + f_code[1][1] = buffer[2] >> 4; + intra_dc_precision = (buffer[2] >> 2) & 3; + picture_structure = buffer[2] & 3; + top_field_first = buffer[3] >> 7; + frame_pred_frame_dct = (buffer[3] >> 6) & 1; + concealment_motion_vectors = (buffer[3] >> 5) & 1; + q_scale_type = (buffer[3] >> 4) & 1; + intra_vlc_format = (buffer[3] >> 3) & 1; + alternate_scan = (buffer[3] >> 2) & 1; + repeat_first_field = (buffer[3] >> 1) & 1; + progressive_frame = buffer[4] >> 7; + + fprintf (stderr, + " (pic_ext) %s\n", picture_structure_str [picture_structure]); + fprintf (stderr, + " (pic_ext) forward horizontal f_code % d, forward vertical f_code % d\n", + f_code[0][0], f_code[0][1]); + fprintf (stderr, + " (pic_ext) backward horizontal f_code % d, backward vertical f_code % d\n", + f_code[1][0], f_code[1][1]); + fprintf (stderr, + " (pic_ext) intra_dc_precision %d, top_field_first %d, frame_pred_frame_dct %d\n", + intra_dc_precision, top_field_first, frame_pred_frame_dct); + fprintf (stderr, + " (pic_ext) concealment_motion_vectors %d, q_scale_type %d, intra_vlc_format %d\n", + concealment_motion_vectors, q_scale_type, intra_vlc_format); + fprintf (stderr, + " (pic_ext) alternate_scan %d, repeat_first_field %d, progressive_frame %d\n", + alternate_scan, repeat_first_field, progressive_frame); +} + +void mpeg2_stats (int code, uint8_t * buffer) +{ + if (! (debug_is_on ())) + return; + + switch (code) { + case 0x00: + stats_picture (buffer); + break; + case 0xb2: + stats_user_data (buffer); + break; + case 0xb3: + stats_sequence (buffer); + break; + case 0xb4: + stats_sequence_error (buffer); + break; + case 0xb5: + switch (buffer[0] >> 4) { + case 1: + stats_sequence_extension (buffer); + break; + case 2: + stats_sequence_display_extension (buffer); + break; + case 3: + stats_quant_matrix_extension (buffer); + break; + case 4: + stats_copyright_extension (buffer); + break; + case 5: + stats_sequence_scalable_extension (buffer); + break; + case 7: + stats_picture_display_extension (buffer); + break; + case 8: + stats_picture_coding_extension (buffer); + break; + default: + fprintf (stderr, " (unknown extension %#x)\n", buffer[0] >> 4); + } + break; + case 0xb7: + stats_sequence_end (buffer); + break; + case 0xb8: + stats_group (buffer); + break; + default: + if (code < 0xb0) + stats_slice (code, buffer); + else + fprintf (stderr, " (unknown start code %#02x)\n", code); + } +} diff --git a/src/video_dec/libmpeg2/vis.h b/src/video_dec/libmpeg2/vis.h new file mode 100644 index 000000000..69dd49075 --- /dev/null +++ b/src/video_dec/libmpeg2/vis.h @@ -0,0 +1,328 @@ +/* + * vis.h + * Copyright (C) 2003 David S. Miller + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/* You may be asking why I hard-code the instruction opcodes and don't + * use the normal VIS assembler mnenomics for the VIS instructions. + * + * The reason is that Sun, in their infinite wisdom, decided that a binary + * using a VIS instruction will cause it to be marked (in the ELF headers) + * as doing so, and this prevents the OS from loading such binaries if the + * current cpu doesn't have VIS. There is no way to easily override this + * behavior of the assembler that I am aware of. + * + * This totally defeats what libmpeg2 is trying to do which is allow a + * single binary to be created, and then detect the availability of VIS + * at runtime. + * + * I'm not saying that tainting the binary by default is bad, rather I'm + * saying that not providing a way to override this easily unnecessarily + * ties people's hands. + * + * Thus, we do the opcode encoding by hand and output 32-bit words in + * the assembler to keep the binary from becoming tainted. + */ + +#define vis_opc_base ((0x1 << 31) | (0x36 << 19)) +#define vis_opf(X) ((X) << 5) +#define vis_sreg(X) (X) +#define vis_dreg(X) (((X)&0x1f)|((X)>>5)) +#define vis_rs1_s(X) (vis_sreg(X) << 14) +#define vis_rs1_d(X) (vis_dreg(X) << 14) +#define vis_rs2_s(X) (vis_sreg(X) << 0) +#define vis_rs2_d(X) (vis_dreg(X) << 0) +#define vis_rd_s(X) (vis_sreg(X) << 25) +#define vis_rd_d(X) (vis_dreg(X) << 25) + +#define vis_ss2s(opf,rs1,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs1_s(rs1) | \ + vis_rs2_s(rs2) | \ + vis_rd_s(rd))) + +#define vis_dd2d(opf,rs1,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs1_d(rs1) | \ + vis_rs2_d(rs2) | \ + vis_rd_d(rd))) + +#define vis_ss2d(opf,rs1,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs1_s(rs1) | \ + vis_rs2_s(rs2) | \ + vis_rd_d(rd))) + +#define vis_sd2d(opf,rs1,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs1_s(rs1) | \ + vis_rs2_d(rs2) | \ + vis_rd_d(rd))) + +#define vis_d2s(opf,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs2_d(rs2) | \ + vis_rd_s(rd))) + +#define vis_s2d(opf,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs2_s(rs2) | \ + vis_rd_d(rd))) + +#define vis_d12d(opf,rs1,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs1_d(rs1) | \ + vis_rd_d(rd))) + +#define vis_d22d(opf,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs2_d(rs2) | \ + vis_rd_d(rd))) + +#define vis_s12s(opf,rs1,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs1_s(rs1) | \ + vis_rd_s(rd))) + +#define vis_s22s(opf,rs2,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rs2_s(rs2) | \ + vis_rd_s(rd))) + +#define vis_s(opf,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rd_s(rd))) + +#define vis_d(opf,rd) \ + __asm__ __volatile__ (".word %0" \ + : : "i" (vis_opc_base | vis_opf(opf) | \ + vis_rd_d(rd))) + +#define vis_r2m(op,rd,mem) \ + __asm__ __volatile__ (#op "\t%%f" #rd ", [%0]" : : "r" (&(mem)) ) + +#define vis_r2m_2(op,rd,mem1,mem2) \ + __asm__ __volatile__ (#op "\t%%f" #rd ", [%0 + %1]" : : "r" (mem1), "r" (mem2) ) + +#define vis_m2r(op,mem,rd) \ + __asm__ __volatile__ (#op "\t[%0], %%f" #rd : : "r" (&(mem)) ) + +#define vis_m2r_2(op,mem1,mem2,rd) \ + __asm__ __volatile__ (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) ) + +static inline void vis_set_gsr(unsigned int _val) +{ + register unsigned int val asm("g1"); + + val = _val; + __asm__ __volatile__(".word 0xa7804000" + : : "r" (val)); +} + +#define VIS_GSR_ALIGNADDR_MASK 0x0000007 +#define VIS_GSR_ALIGNADDR_SHIFT 0 +#define VIS_GSR_SCALEFACT_MASK 0x0000078 +#define VIS_GSR_SCALEFACT_SHIFT 3 + +#define vis_ld32(mem,rs1) vis_m2r(ld, mem, rs1) +#define vis_ld32_2(mem1,mem2,rs1) vis_m2r_2(ld, mem1, mem2, rs1) +#define vis_st32(rs1,mem) vis_r2m(st, rs1, mem) +#define vis_st32_2(rs1,mem1,mem2) vis_r2m_2(st, rs1, mem1, mem2) +#define vis_ld64(mem,rs1) vis_m2r(ldd, mem, rs1) +#define vis_ld64_2(mem1,mem2,rs1) vis_m2r_2(ldd, mem1, mem2, rs1) +#define vis_st64(rs1,mem) vis_r2m(std, rs1, mem) +#define vis_st64_2(rs1,mem1,mem2) vis_r2m_2(std, rs1, mem1, mem2) + +#define vis_ldblk(mem, rd) \ +do { register void *__mem asm("g1"); \ + __mem = &(mem); \ + __asm__ __volatile__(".word 0xc1985e00 | %1" \ + : \ + : "r" (__mem), \ + "i" (vis_rd_d(rd)) \ + : "memory"); \ +} while (0) + +#define vis_stblk(rd, mem) \ +do { register void *__mem asm("g1"); \ + __mem = &(mem); \ + __asm__ __volatile__(".word 0xc1b85e00 | %1" \ + : \ + : "r" (__mem), \ + "i" (vis_rd_d(rd)) \ + : "memory"); \ +} while (0) + +#define vis_membar_storestore() \ + __asm__ __volatile__(".word 0x8143e008" : : : "memory") + +#define vis_membar_sync() \ + __asm__ __volatile__(".word 0x8143e040" : : : "memory") + +/* 16 and 32 bit partitioned addition and subtraction. The normal + * versions perform 4 16-bit or 2 32-bit additions or subtractions. + * The 's' versions perform 2 16-bit or 2 32-bit additions or + * subtractions. + */ + +#define vis_padd16(rs1,rs2,rd) vis_dd2d(0x50, rs1, rs2, rd) +#define vis_padd16s(rs1,rs2,rd) vis_ss2s(0x51, rs1, rs2, rd) +#define vis_padd32(rs1,rs2,rd) vis_dd2d(0x52, rs1, rs2, rd) +#define vis_padd32s(rs1,rs2,rd) vis_ss2s(0x53, rs1, rs2, rd) +#define vis_psub16(rs1,rs2,rd) vis_dd2d(0x54, rs1, rs2, rd) +#define vis_psub16s(rs1,rs2,rd) vis_ss2s(0x55, rs1, rs2, rd) +#define vis_psub32(rs1,rs2,rd) vis_dd2d(0x56, rs1, rs2, rd) +#define vis_psub32s(rs1,rs2,rd) vis_ss2s(0x57, rs1, rs2, rd) + +/* Pixel formatting instructions. */ + +#define vis_pack16(rs2,rd) vis_d2s( 0x3b, rs2, rd) +#define vis_pack32(rs1,rs2,rd) vis_dd2d(0x3a, rs1, rs2, rd) +#define vis_packfix(rs2,rd) vis_d2s( 0x3d, rs2, rd) +#define vis_expand(rs2,rd) vis_s2d( 0x4d, rs2, rd) +#define vis_pmerge(rs1,rs2,rd) vis_ss2d(0x4b, rs1, rs2, rd) + +/* Partitioned multiply instructions. */ + +#define vis_mul8x16(rs1,rs2,rd) vis_sd2d(0x31, rs1, rs2, rd) +#define vis_mul8x16au(rs1,rs2,rd) vis_ss2d(0x33, rs1, rs2, rd) +#define vis_mul8x16al(rs1,rs2,rd) vis_ss2d(0x35, rs1, rs2, rd) +#define vis_mul8sux16(rs1,rs2,rd) vis_dd2d(0x36, rs1, rs2, rd) +#define vis_mul8ulx16(rs1,rs2,rd) vis_dd2d(0x37, rs1, rs2, rd) +#define vis_muld8sux16(rs1,rs2,rd) vis_ss2d(0x38, rs1, rs2, rd) +#define vis_muld8ulx16(rs1,rs2,rd) vis_ss2d(0x39, rs1, rs2, rd) + +/* Alignment instructions. */ + +static inline void *vis_alignaddr(void *_ptr) +{ + register void *ptr asm("g1"); + + ptr = _ptr; + + __asm__ __volatile__(".word %2" + : "=&r" (ptr) + : "0" (ptr), + "i" (vis_opc_base | vis_opf(0x18) | + vis_rs1_s(1) | + vis_rs2_s(0) | + vis_rd_s(1))); + + return ptr; +} + +static inline void vis_alignaddr_g0(void *_ptr) +{ + register void *ptr asm("g1"); + + ptr = _ptr; + + __asm__ __volatile__(".word %2" + : "=&r" (ptr) + : "0" (ptr), + "i" (vis_opc_base | vis_opf(0x18) | + vis_rs1_s(1) | + vis_rs2_s(0) | + vis_rd_s(0))); +} + +static inline void *vis_alignaddrl(void *_ptr) +{ + register void *ptr asm("g1"); + + ptr = _ptr; + + __asm__ __volatile__(".word %2" + : "=&r" (ptr) + : "0" (ptr), + "i" (vis_opc_base | vis_opf(0x19) | + vis_rs1_s(1) | + vis_rs2_s(0) | + vis_rd_s(1))); + + return ptr; +} + +static inline void vis_alignaddrl_g0(void *_ptr) +{ + register void *ptr asm("g1"); + + ptr = _ptr; + + __asm__ __volatile__(".word %2" + : "=&r" (ptr) + : "0" (ptr), + "i" (vis_opc_base | vis_opf(0x19) | + vis_rs1_s(1) | + vis_rs2_s(0) | + vis_rd_s(0))); +} + +#define vis_faligndata(rs1,rs2,rd) vis_dd2d(0x48, rs1, rs2, rd) + +/* Logical operate instructions. */ + +#define vis_fzero(rd) vis_d( 0x60, rd) +#define vis_fzeros(rd) vis_s( 0x61, rd) +#define vis_fone(rd) vis_d( 0x7e, rd) +#define vis_fones(rd) vis_s( 0x7f, rd) +#define vis_src1(rs1,rd) vis_d12d(0x74, rs1, rd) +#define vis_src1s(rs1,rd) vis_s12s(0x75, rs1, rd) +#define vis_src2(rs2,rd) vis_d22d(0x78, rs2, rd) +#define vis_src2s(rs2,rd) vis_s22s(0x79, rs2, rd) +#define vis_not1(rs1,rd) vis_d12d(0x6a, rs1, rd) +#define vis_not1s(rs1,rd) vis_s12s(0x6b, rs1, rd) +#define vis_not2(rs2,rd) vis_d22d(0x66, rs2, rd) +#define vis_not2s(rs2,rd) vis_s22s(0x67, rs2, rd) +#define vis_or(rs1,rs2,rd) vis_dd2d(0x7c, rs1, rs2, rd) +#define vis_ors(rs1,rs2,rd) vis_ss2s(0x7d, rs1, rs2, rd) +#define vis_nor(rs1,rs2,rd) vis_dd2d(0x62, rs1, rs2, rd) +#define vis_nors(rs1,rs2,rd) vis_ss2s(0x63, rs1, rs2, rd) +#define vis_and(rs1,rs2,rd) vis_dd2d(0x70, rs1, rs2, rd) +#define vis_ands(rs1,rs2,rd) vis_ss2s(0x71, rs1, rs2, rd) +#define vis_nand(rs1,rs2,rd) vis_dd2d(0x6e, rs1, rs2, rd) +#define vis_nands(rs1,rs2,rd) vis_ss2s(0x6f, rs1, rs2, rd) +#define vis_xor(rs1,rs2,rd) vis_dd2d(0x6c, rs1, rs2, rd) +#define vis_xors(rs1,rs2,rd) vis_ss2s(0x6d, rs1, rs2, rd) +#define vis_xnor(rs1,rs2,rd) vis_dd2d(0x72, rs1, rs2, rd) +#define vis_xnors(rs1,rs2,rd) vis_ss2s(0x73, rs1, rs2, rd) +#define vis_ornot1(rs1,rs2,rd) vis_dd2d(0x7a, rs1, rs2, rd) +#define vis_ornot1s(rs1,rs2,rd) vis_ss2s(0x7b, rs1, rs2, rd) +#define vis_ornot2(rs1,rs2,rd) vis_dd2d(0x76, rs1, rs2, rd) +#define vis_ornot2s(rs1,rs2,rd) vis_ss2s(0x77, rs1, rs2, rd) +#define vis_andnot1(rs1,rs2,rd) vis_dd2d(0x68, rs1, rs2, rd) +#define vis_andnot1s(rs1,rs2,rd) vis_ss2s(0x69, rs1, rs2, rd) +#define vis_andnot2(rs1,rs2,rd) vis_dd2d(0x64, rs1, rs2, rd) +#define vis_andnot2s(rs1,rs2,rd) vis_ss2s(0x65, rs1, rs2, rd) + +/* Pixel component distance. */ + +#define vis_pdist(rs1,rs2,rd) vis_dd2d(0x3e, rs1, rs2, rd) diff --git a/src/video_dec/libmpeg2/vlc.h b/src/video_dec/libmpeg2/vlc.h new file mode 100644 index 000000000..65de9a840 --- /dev/null +++ b/src/video_dec/libmpeg2/vlc.h @@ -0,0 +1,428 @@ +/* + * vlc.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#define GETWORD(bit_buf,shift,bit_ptr) \ +do { \ + bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \ + bit_ptr += 2; \ +} while (0) + +static inline void bitstream_init (picture_t * picture, uint8_t * start) +{ + picture->bitstream_buf = + (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3]; + picture->bitstream_ptr = start + 4; + picture->bitstream_bits = -16; +} + +/* make sure that there are at least 16 valid bits in bit_buf */ +#define NEEDBITS(bit_buf,bits,bit_ptr) \ +do { \ + if (bits > 0) { \ + GETWORD (bit_buf, bits, bit_ptr); \ + bits -= 16; \ + } \ +} while (0) + +/* remove num valid bits from bit_buf */ +#define DUMPBITS(bit_buf,bits,num) \ +do { \ + bit_buf <<= (num); \ + bits += (num); \ +} while (0) + +/* take num bits from the high part of bit_buf and zero extend them */ +#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num))) + +/* take num bits from the high part of bit_buf and sign extend them */ +#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num))) + +typedef struct { + uint8_t modes; + uint8_t len; +} MBtab; + +typedef struct { + uint8_t delta; + uint8_t len; +} MVtab; + +typedef struct { + int8_t dmv; + uint8_t len; +} DMVtab; + +typedef struct { + uint8_t cbp; + uint8_t len; +} CBPtab; + +typedef struct { + uint8_t size; + uint8_t len; +} DCtab; + +typedef struct { + uint8_t run; + uint8_t level; + uint8_t len; +} DCTtab; + +typedef struct { + uint8_t mba; + uint8_t len; +} MBAtab; + + +#define INTRA MACROBLOCK_INTRA +#define QUANT MACROBLOCK_QUANT + +static const MBtab MB_I [] = { + {INTRA|QUANT, 2}, {INTRA, 1} +}; + +#define MC MACROBLOCK_MOTION_FORWARD +#define CODED MACROBLOCK_PATTERN + +static const MBtab MB_P [] = { + {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5}, + {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3}, + {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, + {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1} +}; + +#define FWD MACROBLOCK_MOTION_FORWARD +#define BWD MACROBLOCK_MOTION_BACKWARD +#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD + +static const MBtab MB_B [] = { + {0, 0}, {INTRA|QUANT, 6}, + {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6}, + {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5}, + {INTRA, 5}, {INTRA, 5}, + {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4}, + {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, + {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, + {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, + {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, + {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2} +}; + +#undef INTRA +#undef QUANT +#undef MC +#undef CODED +#undef FWD +#undef BWD +#undef INTER + + +static const MVtab MV_4 [] = { + { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} +}; + +static const MVtab MV_10 [] = { + { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, + { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10}, + {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9}, + { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, + { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, + { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7} +}; + + +static const DMVtab DMV_2 [] = { + { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} +}; + + +static const CBPtab CBP_7 [] = { + {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7}, + {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7}, + {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6}, + {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6}, + {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, + {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5}, + {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, + {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5}, + {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5}, + {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5}, + {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, + {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, + {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5}, + {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5}, + {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5}, + {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, + {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, + {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, + {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, + {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, + {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, + {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, + {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, + {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3} +}; + +static const CBPtab CBP_9 [] = { + {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9}, + {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9}, + {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8}, + {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8}, + {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8}, + {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8}, + {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8}, + {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8}, + {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8}, + {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8}, + {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8}, + {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8}, + {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8}, + {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8}, + {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8}, + {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8} +}; + + +static const DCtab DC_lum_5 [] = { + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5} +}; + +static const DCtab DC_chrom_5 [] = { + {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5} +}; + +static const DCtab DC_long [] = { + {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, + {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, + {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6}, + {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9} +}; + + +static const DCTtab DCT_16 [] = { + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0}, + { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0}, + { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0}, + { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0} +}; + +static const DCTtab DCT_15 [] = { + { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15}, + { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15}, + { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15}, + { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15}, + { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14}, + { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14}, + { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14}, + { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14}, + { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14}, + { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14}, + { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14}, + { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14} +}; + +static const DCTtab DCT_13 [] = { + { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13}, + { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13}, + { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13}, + { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13}, + { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12}, + { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12}, + { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12}, + { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12}, + { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12}, + { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12}, + { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12}, + { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12} +}; + +static const DCTtab DCT_B14_10 [] = { + { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10}, + { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10} +}; + +static const DCTtab DCT_B14_8 [] = { + { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, + { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7}, + { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7}, + { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, + { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, + { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, + { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, + { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8}, + { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8} +}; + +static const DCTtab DCT_B14AC_5 [] = { + { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, + { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, + {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2} +}; + +static const DCTtab DCT_B14DC_5 [] = { + { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, + { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1} +}; + +static const DCTtab DCT_B15_10 [] = { + { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9}, + { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9} +}; + +static const DCTtab DCT_B15_8 [] = { + { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, + { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7}, + { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7}, + { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, + { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, + { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, + { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, + { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8}, + { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8}, + { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, + { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, + { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, + { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, + { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, + { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, + { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, + { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, + { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, + { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7}, + { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7}, + { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8}, + { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8} +}; + + +static const MBAtab MBA_5 [] = { + {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} +}; + +static const MBAtab MBA_11 [] = { + {32, 11}, {31, 11}, {30, 11}, {29, 11}, + {28, 11}, {27, 11}, {26, 11}, {25, 11}, + {24, 11}, {23, 11}, {22, 11}, {21, 11}, + {20, 10}, {20, 10}, {19, 10}, {19, 10}, + {18, 10}, {18, 10}, {17, 10}, {17, 10}, + {16, 10}, {16, 10}, {15, 10}, {15, 10}, + {14, 8}, {14, 8}, {14, 8}, {14, 8}, + {14, 8}, {14, 8}, {14, 8}, {14, 8}, + {13, 8}, {13, 8}, {13, 8}, {13, 8}, + {13, 8}, {13, 8}, {13, 8}, {13, 8}, + {12, 8}, {12, 8}, {12, 8}, {12, 8}, + {12, 8}, {12, 8}, {12, 8}, {12, 8}, + {11, 8}, {11, 8}, {11, 8}, {11, 8}, + {11, 8}, {11, 8}, {11, 8}, {11, 8}, + {10, 8}, {10, 8}, {10, 8}, {10, 8}, + {10, 8}, {10, 8}, {10, 8}, {10, 8}, + { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, + { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7} +}; diff --git a/src/video_dec/libmpeg2/xine_mpeg2_decoder.c b/src/video_dec/libmpeg2/xine_mpeg2_decoder.c new file mode 100644 index 000000000..3a3e28452 --- /dev/null +++ b/src/video_dec/libmpeg2/xine_mpeg2_decoder.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * stuff needed to turn libmpeg2 into a xine decoder plugin + */ + + +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "mpeg2_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include + +typedef struct { + video_decoder_class_t decoder_class; +} mpeg2_class_t; + + +typedef struct mpeg2dec_decoder_s { + video_decoder_t video_decoder; + mpeg2dec_t mpeg2; + mpeg2_class_t *class; + xine_stream_t *stream; +} mpeg2dec_decoder_t; + +static void mpeg2dec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; + + lprintf ("decode_data, flags=0x%08x ...\n", buf->decoder_flags); + + /* handle aspect hints from xine-dvdnav */ + if (buf->decoder_flags & BUF_FLAG_SPECIAL) { + if (buf->decoder_info[1] == BUF_SPECIAL_ASPECT) { + this->mpeg2.force_aspect = buf->decoder_info[2]; + if (buf->decoder_info[3] == 0x1 && buf->decoder_info[2] == 3) + /* letterboxing is denied, we have to do pan&scan */ + this->mpeg2.force_pan_scan = 1; + else + this->mpeg2.force_pan_scan = 0; + } + return; + } + + if (buf->decoder_flags & BUF_FLAG_PREVIEW) { + mpeg2_find_sequence_header (&this->mpeg2, buf->content, buf->content + buf->size); + } else { + + mpeg2_decode_data (&this->mpeg2, buf->content, buf->content + buf->size, + buf->pts); + } + + lprintf ("decode_data...done\n"); +} + +static void mpeg2dec_flush (video_decoder_t *this_gen) { + mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; + + lprintf ("flush\n"); + + mpeg2_flush (&this->mpeg2); +} + +static void mpeg2dec_reset (video_decoder_t *this_gen) { + mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; + + mpeg2_reset (&this->mpeg2); +} + +static void mpeg2dec_discontinuity (video_decoder_t *this_gen) { + mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; + + mpeg2_discontinuity (&this->mpeg2); +} + +static void mpeg2dec_dispose (video_decoder_t *this_gen) { + + mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen; + + lprintf ("close\n"); + + mpeg2_close (&this->mpeg2); + + 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) { + mpeg2dec_decoder_t *this ; + + this = (mpeg2dec_decoder_t *) xine_xmalloc (sizeof (mpeg2dec_decoder_t)); + + this->video_decoder.decode_data = mpeg2dec_decode_data; + this->video_decoder.flush = mpeg2dec_flush; + this->video_decoder.reset = mpeg2dec_reset; + this->video_decoder.discontinuity = mpeg2dec_discontinuity; + this->video_decoder.dispose = mpeg2dec_dispose; + this->stream = stream; + this->class = (mpeg2_class_t *) class_gen; + this->mpeg2.stream = stream; + + mpeg2_init (&this->mpeg2, stream->video_out); + (stream->video_out->open) (stream->video_out, stream); + this->mpeg2.force_aspect = this->mpeg2.force_pan_scan = 0; + + return &this->video_decoder; +} + +/* + * mpeg2 plugin class + */ +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.identifier = "mpeg2dec"; + this->decoder_class.description = N_("mpeg2 based video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 }; + +static const decoder_info_t dec_info_mpeg2 = { + supported_types, /* supported types */ + 7 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "mpeg2", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/libmpeg2/xvmc.h b/src/video_dec/libmpeg2/xvmc.h new file mode 100644 index 000000000..5d61bcf83 --- /dev/null +++ b/src/video_dec/libmpeg2/xvmc.h @@ -0,0 +1,32 @@ +/* + * mpeg2_internal.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#ifndef _XVMC_H +#include "libmpeg2_accel.h" + +/* slice_xvmc.c */ + +void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer); +void xvmc_setup_scan_ptable( void ); + +#endif diff --git a/src/video_dec/libmpeg2/xvmc_vld.h b/src/video_dec/libmpeg2/xvmc_vld.h new file mode 100644 index 000000000..561d1789d --- /dev/null +++ b/src/video_dec/libmpeg2/xvmc_vld.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2004 The Unichrome project. All rights reserved. + * + * This program 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTIES OR REPRESENTATIONS; 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. + * + * + */ + +#ifndef _XVMC_VLD_H +#define _XVMC_VLD_H + +#include "accel_xvmc.h" +#include "xvmc.h" + +extern void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture, + int code, uint8_t *buffer, uint32_t chunk_size, + uint8_t *chunk_buffer); +extern void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code); + + +#endif -- cgit v1.2.3 From 188d7498b854233ac5f329fa342b16cbe1087d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 23:39:35 +0100 Subject: Move all the SubPicture decoders together in the spu_dec directory. Remove superfluous xine_ prefixes from source files. --HG-- rename : src/libspucc/cc_decoder.c => src/spu_dec/cc_decoder.c rename : src/libspucc/cc_decoder.h => src/spu_dec/cc_decoder.h rename : src/libspucmml/xine_cmml_decoder.c => src/spu_dec/cmml_decoder.c rename : src/libspudec/nav_read.c => src/spu_dec/nav_read.c rename : src/libspudec/xine_spu_decoder.c => src/spu_dec/spu_decoder.c rename : src/libspudec/spudec.c => src/spu_dec/spudec.c rename : src/libspudec/spudec.h => src/spu_dec/spudec.h rename : src/libspudvb/xine_spudvb_decoder.c => src/spu_dec/spudvb_decoder.c rename : src/libsputext/xine_sputext_decoder.c => src/spu_dec/sputext_decoder.c rename : src/libsputext/demux_sputext.c => src/spu_dec/sputext_demuxer.c rename : src/libspucc/xine_cc_decoder.c => src/spu_dec/xine_cc_decoder.c --- src/Makefile.am | 6 +- src/libspucc/Makefile.am | 12 - src/libspucc/cc_decoder.c | 1484 -------------------------------- src/libspucc/cc_decoder.h | 87 -- src/libspucc/xine_cc_decoder.c | 353 -------- src/libspucmml/Makefile.am | 9 - src/libspucmml/xine_cmml_decoder.c | 537 ------------ src/libspudec/Makefile.am | 21 - src/libspudec/nav_read.c | 1 - src/libspudec/spudec.c | 1026 ----------------------- src/libspudec/spudec.h | 142 ---- src/libspudec/xine_spu_decoder.c | 381 --------- src/libspudvb/Makefile.am | 9 - src/libspudvb/xine_spudvb_decoder.c | 999 ---------------------- src/libsputext/Makefile.am | 12 - src/libsputext/demux_sputext.c | 1489 --------------------------------- src/libsputext/xine_sputext_decoder.c | 992 ---------------------- src/spu_dec/Makefile.am | 39 + src/spu_dec/cc_decoder.c | 1484 ++++++++++++++++++++++++++++++++ src/spu_dec/cc_decoder.h | 87 ++ src/spu_dec/cmml_decoder.c | 537 ++++++++++++ src/spu_dec/nav_read.c | 1 + src/spu_dec/spu_decoder.c | 381 +++++++++ src/spu_dec/spudec.c | 1026 +++++++++++++++++++++++ src/spu_dec/spudec.h | 142 ++++ src/spu_dec/spudvb_decoder.c | 999 ++++++++++++++++++++++ src/spu_dec/sputext_decoder.c | 992 ++++++++++++++++++++++ src/spu_dec/sputext_demuxer.c | 1489 +++++++++++++++++++++++++++++++++ src/spu_dec/xine_cc_decoder.c | 353 ++++++++ 29 files changed, 7531 insertions(+), 7559 deletions(-) delete mode 100644 src/libspucc/Makefile.am delete mode 100644 src/libspucc/cc_decoder.c delete mode 100644 src/libspucc/cc_decoder.h delete mode 100644 src/libspucc/xine_cc_decoder.c delete mode 100644 src/libspucmml/Makefile.am delete mode 100644 src/libspucmml/xine_cmml_decoder.c delete mode 100644 src/libspudec/Makefile.am delete mode 100644 src/libspudec/nav_read.c delete mode 100644 src/libspudec/spudec.c delete mode 100644 src/libspudec/spudec.h delete mode 100644 src/libspudec/xine_spu_decoder.c delete mode 100644 src/libspudvb/Makefile.am delete mode 100644 src/libspudvb/xine_spudvb_decoder.c delete mode 100644 src/libsputext/Makefile.am delete mode 100644 src/libsputext/demux_sputext.c delete mode 100644 src/libsputext/xine_sputext_decoder.c create mode 100644 src/spu_dec/Makefile.am create mode 100644 src/spu_dec/cc_decoder.c create mode 100644 src/spu_dec/cc_decoder.h create mode 100644 src/spu_dec/cmml_decoder.c create mode 100644 src/spu_dec/nav_read.c create mode 100644 src/spu_dec/spu_decoder.c create mode 100644 src/spu_dec/spudec.c create mode 100644 src/spu_dec/spudec.h create mode 100644 src/spu_dec/spudvb_decoder.c create mode 100644 src/spu_dec/sputext_decoder.c create mode 100644 src/spu_dec/sputext_demuxer.c create mode 100644 src/spu_dec/xine_cc_decoder.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a94673fb7..c9d9497ae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,14 +8,10 @@ SUBDIRS = \ audio_dec \ video_out \ video_dec \ + spu_dec \ dxr3 \ input \ demuxers \ - libspudec \ - libspucc \ - libspucmml \ - libspudvb \ - libsputext \ libw32dll \ libreal \ post \ diff --git a/src/libspucc/Makefile.am b/src/libspucc/Makefile.am deleted file mode 100644 index 87266505c..000000000 --- a/src/libspucc/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -noinst_HEADERS = cc_decoder.h - -xineplug_LTLIBRARIES = xineplug_decode_spucc.la - -xineplug_decode_spucc_la_SOURCES = cc_decoder.c xine_cc_decoder.c -xineplug_decode_spucc_la_LIBADD = $(XINE_LIB) -xineplug_decode_spucc_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing diff --git a/src/libspucc/cc_decoder.c b/src/libspucc/cc_decoder.c deleted file mode 100644 index e8fc09895..000000000 --- a/src/libspucc/cc_decoder.c +++ /dev/null @@ -1,1484 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * Copyright (C) Christian Vogler - * cvogler@gradient.cis.upenn.edu - December 2001 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stuff needed to provide closed captioning decoding and display - * - * Some small bits and pieces of the EIA-608 captioning decoder were - * adapted from CCDecoder 0.9.1 by Mike Baker. The latest version is - * available at http://sourceforge.net/projects/ccdecoder/. - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include "cc_decoder.h" -#include - -/* -#define LOG_DEBUG 3 -*/ - -/* at 29.97 fps, each NTSC frame takes 3003 metronom ticks on the average. */ -#define NTSC_FRAME_DURATION 3003 - -#define CC_ROWS 15 -#define CC_COLUMNS 32 -#define CC_CHANNELS 2 - -/* 1 is the caption background color index in the OSD palettes. */ -#define CAP_BG_COL 1 - -/* number of text colors specified by EIA-608 standard */ -#define NUM_FG_COL 7 - -#ifndef WIN32 -/* colors specified by the EIA 608 standard */ -enum { WHITE, GREEN, BLUE, CYAN, RED, YELLOW, MAGENTA, BLACK, TRANSPARENT }; -#else -/* colors specified by the EIA 608 standard */ -enum { WHITE, GREEN, BLUE, CYAN, RED, YELLOW, MAGENTA, BLACK }; -#endif - - - -/* color mapping to OSD text color indices */ -static const int text_colormap[NUM_FG_COL] = { - OSD_TEXT1, OSD_TEXT2, OSD_TEXT3, OSD_TEXT4, OSD_TEXT5, OSD_TEXT6, OSD_TEXT7 -}; - - -/* -------------------- caption text colors -----------------------------*/ -/* FIXME: The colors look fine on an XShm display, but they look *terrible* - with the Xv display on the NVidia driver on a GeForce 3. The colors bleed - into each other more than I'd expect from the downsampling into YUV - colorspace. - At this moment, it looks like a problem in the Xv YUV blending functions. -*/ -typedef struct colorinfo_s { - clut_t bgcol; /* text background color */ - clut_t bordercol; /* text border color */ - clut_t textcol; /* text color */ -} colorinfo_t; - - -static const colorinfo_t cc_text_trans[NUM_FG_COL] = { - /* white, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80) - }, - - /* green, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x90, 0x22, 0x35) - }, - - /* blue, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x29, 0x6e, 0xff) - }, - - /* cyan, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xaa, 0x10, 0xa6) - }, - - /* red, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x52, 0xf0, 0x5a) - }, - - /* yellow, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xd4, 0x92, 0x10) - }, - - /* magenta, black border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x6b, 0xde, 0xca) - } -}; - -static const colorinfo_t cc_text_solid[NUM_FG_COL] = { - /* white, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80) - }, - - /* green, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x90, 0x22, 0x35) - }, - - /* blue, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x29, 0x6e, 0xff) - }, - - /* cyan, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xaa, 0x10, 0xa6) - }, - - /* red, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x52, 0xf0, 0x5a) - }, - - /* yellow, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xd4, 0x92, 0x10) - }, - - /* magenta, black border, solid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x6b, 0xde, 0xca) - } -}; - - -static const uint8_t cc_text_trans_alpha[TEXT_PALETTE_SIZE] = { - 0, 8, 9, 10, 11, 12, 15, 15, 15, 15, 15 -}; - -static const uint8_t cc_text_solid_alpha[TEXT_PALETTE_SIZE] = { - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 -}; - - -static const colorinfo_t *const cc_text_palettes[NUM_CC_PALETTES] = { - cc_text_trans, - cc_text_solid -}; - -static const uint8_t *const cc_alpha_palettes[NUM_CC_PALETTES] = { - cc_text_trans_alpha, - cc_text_solid_alpha -}; - -/* --------------------- misc. EIA 608 definitions -------------------*/ - -#define TRANSP_SPACE 0x19 /* code for transparent space, essentially - arbitrary */ - -#define MAX(a, b) ((a) > (b)? (a) : (b)) - -/* mapping from PAC row code to actual CC row */ -static const int rowdata[] = {10, -1, 0, 1, 2, 3, 11, 12, 13, 14, 4, 5, 6, - 7, 8, 9}; -/* FIXME: do real ™ (U+2122) */ -/* Code 182 must be mapped as a musical note ('♪', U+266A) in the caption font */ -static const char specialchar[] = { - 174 /* ® */, 176 /* ° */, 189 /* ½ */, 191 /* ¿ */, - 'T' /* ™ */, 162 /* ¢ */, 163 /* £ */, 182 /* ¶ => ♪ */, - 224 /* à */, TRANSP_SPACE,232 /* è */, 226 /* â */, - 234 /* ê */, 238 /* î */, 244 /* ô */, 251 /* û */ -}; - -/* character translation table - EIA 608 codes are not all the same as ASCII */ -static char chartbl[128]; - -/* CC codes use odd parity for error detection, since they originally were */ -/* transmitted via noisy video signals */ -static int parity_table[256]; - - -/*---------------- decoder data structures -----------------------*/ - -/* CC renderer */ -struct cc_renderer_s { - int video_width; /* video dimensions */ - int video_height; - - int x; /* coordinates of the captioning area */ - int y; - int width; - int height; - int max_char_height; /* captioning font properties */ - int max_char_width; - - osd_renderer_t *osd_renderer; /* active OSD renderer */ - osd_object_t *cap_display; /* caption display object */ - int displayed; /* true when caption currently is displayed */ - - /* the next variable is a hack: hiding a caption with vpts 0 doesn't seem - to work if the caption has been registered in the SPU event queue, but - not yet displayed. So we remember the vpts of the show event, and use - that as the vpts of the hide event upon an osd free. - */ -/*FIXME: bug in OSD or SPU?*/ - int64_t display_vpts; /* vpts of currently displayed caption */ - - /* this variable is an even worse hack: in some rare cases, the pts - information on the DVD gets out of sync with the caption information. - If this happens, the vpts of a hide caption event can actually be - slightly higher than the vpts of the following show caption event. - For this reason, we remember the vpts of the hide event and force - the next show event's vpts to be at least equal to the hide event's - vpts. - */ - int64_t last_hide_vpts; - - /* caption palette and alpha channel */ - uint32_t cc_palette[OVL_PALETTE_SIZE]; - uint8_t cc_trans[OVL_PALETTE_SIZE]; - - metronom_t *metronom; /* the active xine metronom */ - - cc_state_t *cc_state; /* captioning configuration */ -}; - - -/* CC attribute */ -typedef struct cc_attribute_s { - uint8_t italic; - uint8_t underline; - uint8_t foreground; - uint8_t background; -} cc_attribute_t; - -/* CC character cell */ -typedef struct cc_char_cell_s { - uint8_t c; /* character code, not the same as ASCII */ - cc_attribute_t attributes; /* attributes of this character, if changed */ - /* here */ - int midrow_attr; /* true if this cell changes an attribute */ -} cc_char_cell_t; - -/* a single row in the closed captioning memory */ -typedef struct cc_row_s { - cc_char_cell_t cells[CC_COLUMNS]; - int pos; /* position of the cursor */ - int num_chars; /* how many characters in the row are data */ - int attr_chg; /* true if midrow attr. change at cursor pos */ - int pac_attr_chg; /* true if attribute has changed via PAC */ - cc_attribute_t pac_attr; /* PAC attr. that hasn't been applied yet */ -} cc_row_t; - -/* closed captioning memory for a single channel */ -typedef struct cc_buffer_s { - cc_row_t rows[CC_ROWS]; - int rowpos; /* row cursor position */ -} cc_buffer_t; - -/* captioning memory for all channels */ -typedef struct cc_memory_s { - cc_buffer_t channel[CC_CHANNELS]; - int channel_no; /* currently active channel */ -} cc_memory_t; - -/* The closed captioning decoder data structure */ -struct cc_decoder_s { - /* CC decoder buffer - one onscreen, one offscreen */ - cc_memory_t buffer[2]; - /* onscreen, offscreen buffer ptrs */ - cc_memory_t *on_buf; - cc_memory_t *off_buf; - /* which buffer is active for receiving data */ - cc_memory_t **active; - - /* for logging and debugging purposes, captions are assigned increasing */ - /* unique ids. */ - uint32_t capid; - - /* the last captioning code seen (control codes are often sent twice - in a row, but should be processed only once) */ - uint32_t lastcode; - - /* The PTS and SCR at which the captioning chunk started */ - int64_t pts; - /* holds the NTSC frame offset to last known pts/scr */ - uint32_t f_offset; - - /* active OSD renderer */ - osd_renderer_t *renderer; - /* true when caption currently is displayed */ - int displayed; - - /* configuration and intrinsics of CC decoder */ - cc_state_t *cc_state; - - metronom_t *metronom; -}; - - -/*---------------- general utility functions ---------------------*/ - -static void get_font_metrics(osd_renderer_t *renderer, - const char *fontname, int font_size, - int *maxw, int *maxh) -{ - int c; - osd_object_t *testc = renderer->new_object(renderer, 640, 480); - - *maxw = 0; - *maxh = 0; - - renderer->set_font(testc, (char *) fontname, font_size); - renderer->set_encoding(testc, "iso-8859-1"); - for (c = 32; c < 256; c++) { - int tw, th; - char buf[2]; - - buf[0] = (char)c; - buf[1] = '\0'; - - renderer->get_text_size(testc, buf, &tw, &th); - *maxw = MAX(*maxw, tw); - *maxh = MAX(*maxh, th); - } - renderer->free_object(testc); -} - - -static int parity(uint8_t byte) -{ - int i; - int ones = 0; - - for (i = 0; i < 7; i++) { - if (byte & (1 << i)) - ones++; - } - - return ones & 1; -} - - -static void build_parity_table(void) -{ - uint8_t byte; - int parity_v; - for (byte = 0; byte <= 127; byte++) { - parity_v = parity(byte); - /* CC uses odd parity (i.e., # of 1's in byte is odd.) */ - parity_table[byte] = parity_v; - parity_table[byte | 0x80] = !parity_v; - } -} - - -static int good_parity(uint16_t data) -{ - int ret = parity_table[data & 0xff] && parity_table[(data & 0xff00) >> 8]; - if (! ret) - printf("Bad parity in EIA-608 data (%x)\n", data); - return ret; -} - - -static void build_char_table(void) -{ - int i; - /* first the normal ASCII codes */ - for (i = 0; i < 128; i++) - chartbl[i] = (char) i; - /* now the special codes */ - chartbl[0x2a] = 225; /* á */ - chartbl[0x5c] = 233; /* é */ - chartbl[0x5e] = 237; /* í */ - chartbl[0x5f] = 243; /* ó */ - chartbl[0x60] = 250; /* ú */ - chartbl[0x7b] = 231; /* ç */ - chartbl[0x7c] = 247; /* ÷ */ - chartbl[0x7d] = 209; /* Ñ */ - chartbl[0x7e] = 241; /* ñ */ - chartbl[0x7f] = 164; /* ¤ FIXME: should be a solid block ('█'; U+2588) */ -} - - -static clut_t interpolate_color(clut_t src, clut_t dest, int steps, - int current_step) -{ - int diff_y = ((int) dest.y) - ((int) src.y); - int diff_cr = ((int) dest.cr) - ((int) src.cr); - int diff_cb = ((int) dest.cb) - ((int) src.cb); - int res_y = ((int) src.y) + (diff_y * current_step / (steps + 1)); - int res_cr = ((int) src.cr) + (diff_cr * current_step / (steps + 1)); - int res_cb = ((int) src.cb) + (diff_cb * current_step / (steps + 1)); -#if __SUNPRO_C - /* - * Sun's Forte compiler refuses to initialize automatic structure - * variable with bitfields, so we use explicit assignments for now. - */ - clut_t res; - res.y = res_y; - res.cr = res_cr; - res.cb = res_cb; - res.foo = 0; -#else - clut_t res = CLUT_Y_CR_CB_INIT((uint8_t) res_y, (uint8_t) res_cr, - (uint8_t) res_cb); -#endif - return res; -} - -/*----------------- cc_row_t methods --------------------------------*/ - -static void ccrow_fill_transp(cc_row_t *rowbuf){ - int i; - -#ifdef LOG_DEBUG - printf("cc_decoder: ccrow_fill_transp: Filling in %d transparent spaces.\n", - rowbuf->pos - rowbuf->num_chars); -#endif - for (i = rowbuf->num_chars; i < rowbuf->pos; i++) { - rowbuf->cells[i].c = TRANSP_SPACE; - rowbuf->cells[i].midrow_attr = 0; - } -} - - -static int ccrow_find_next_text_part(cc_row_t *this, int pos) -{ - while (pos < this->num_chars && this->cells[pos].c == TRANSP_SPACE) - pos++; - return pos; -} - - -static int ccrow_find_end_of_text_part(cc_row_t *this, int pos) -{ - while (pos < this->num_chars && this->cells[pos].c != TRANSP_SPACE) - pos++; - return pos; -} - - -static int ccrow_find_current_attr(cc_row_t *this, int pos) -{ - while (pos > 0 && !this->cells[pos].midrow_attr) - pos--; - return pos; -} - - -static int ccrow_find_next_attr_change(cc_row_t *this, int pos, int lastpos) -{ - pos++; - while (pos < lastpos && !this->cells[pos].midrow_attr) - pos++; - return pos; -} - - -static void ccrow_set_attributes(cc_renderer_t *renderer, cc_row_t *this, - int pos) -{ - const cc_attribute_t *attr = &this->cells[pos].attributes; - const char *fontname; - cc_config_t *cap_info = renderer->cc_state->cc_cfg; - - if (attr->italic) - fontname = cap_info->italic_font; - else - fontname = cap_info->font; - renderer->osd_renderer->set_font(renderer->cap_display, (char *) fontname, - cap_info->font_size); -} - - -static void ccrow_render(cc_renderer_t *renderer, cc_row_t *this, int rownum) -{ - char buf[CC_COLUMNS + 1]; - int base_y; - int pos = ccrow_find_next_text_part(this, 0); - cc_config_t *cap_info = renderer->cc_state->cc_cfg; - osd_renderer_t *osd_renderer = renderer->osd_renderer; - - /* find y coordinate of caption */ - if (cap_info->center) { - /* find y-center of the desired row; the next line computes */ - /* cap_info->height * (rownum + 0.5) / CC_ROWS */ - /* in integer arithmetic for this purpose. */ - base_y = (renderer->height * rownum * 100 + renderer->height * 50) / - (CC_ROWS * 100); - } - else - base_y = renderer->height * rownum / CC_ROWS; - - /* break down captions into parts separated by transparent space, and */ - /* center each part individually along the x axis */ - while (pos < this->num_chars) { - int endpos = ccrow_find_end_of_text_part(this, pos); - int seg_begin = pos; - int seg_end; - int i; - int text_w = 0, text_h = 0; - int x, y; - int seg_w, seg_h; - int seg_pos[CC_COLUMNS + 1]; - int seg_attr[CC_COLUMNS]; - int cumulative_seg_width[CC_COLUMNS + 1]; - int num_seg = 0; - int seg; - - /* break down each part into segments bounded by attribute changes and */ - /* find text metrics of the parts */ - seg_pos[0] = seg_begin; - cumulative_seg_width[0] = 0; - while (seg_begin < endpos) { - int attr_pos = ccrow_find_current_attr(this, seg_begin); - seg_end = ccrow_find_next_attr_change(this, seg_begin, endpos); - - /* compute text size of segment */ - for (i = seg_begin; i < seg_end; i++) - buf[i - seg_begin] = this->cells[i].c; - buf[seg_end - seg_begin] = '\0'; - ccrow_set_attributes(renderer, this, attr_pos); - osd_renderer->get_text_size(renderer->cap_display, buf, - &seg_w, &seg_h); - - /* update cumulative segment statistics */ - text_w += seg_w; - text_h += seg_h; - seg_pos[num_seg + 1] = seg_end; - seg_attr[num_seg] = attr_pos; - cumulative_seg_width[num_seg + 1] = text_w; - num_seg++; - - seg_begin = seg_end; - } - - /* compute x coordinate of part */ - if (cap_info->center) { - int cell_width = renderer->width / CC_COLUMNS; - x = (renderer->width * (pos + endpos) / 2) / CC_COLUMNS; - x -= text_w / 2; - /* clamp x coordinate to nearest character cell */ - x = ((x + cell_width / 2) / CC_COLUMNS) * CC_COLUMNS + cell_width; - y = base_y - (renderer->max_char_height + 1) / 2; - } - else { - x = renderer->width * pos / CC_COLUMNS; - y = base_y; - } - -#ifdef LOG_DEBUG - printf("text_w, text_h = %d, %d\n", text_w, text_h); - printf("cc from %d to %d; text plotting from %d, %d (basey = %d)\n", pos, endpos, x, y, base_y); -#endif - - /* render text part by rendering each attributed text segment */ - for (seg = 0; seg < num_seg; seg++) { - int textcol = text_colormap[this->cells[seg_attr[seg]].attributes.foreground]; - int box_x1 = x + cumulative_seg_width[seg]; - int box_x2 = x + cumulative_seg_width[seg + 1]; - -#ifdef LOG_DEBUG - printf("ccrow_render: rendering segment %d from %d to %d / %d to %d\n", - seg, seg_pos[seg], seg_pos[seg + 1], - x + cumulative_seg_width[seg], x + cumulative_seg_width[seg + 1]); -#endif - /* make caption background a uniform box. Without this line, the */ - /* background is uneven for superscript characters. */ - /* Also pad left & right ends of caption to make it more readable */ -/*FIXME: There may be off-by one errors in the rendering - check with Miguel*/ - if (seg == 0) - box_x1 -= renderer->max_char_width; - if (seg == num_seg - 1) - box_x2 += renderer->max_char_width; - osd_renderer->filled_rect(renderer->cap_display, box_x1, y, box_x2, - y + renderer->max_char_height, - textcol + CAP_BG_COL); - - for (i = seg_pos[seg]; i < seg_pos[seg + 1]; i++) - buf[i - seg_pos[seg]] = this->cells[i].c; - buf[seg_pos[seg + 1] - seg_pos[seg]] = '\0'; - ccrow_set_attributes(renderer, this, seg_attr[seg]); - - /* text is already mapped from EIA-608 into iso-8859-1 */ - osd_renderer->render_text(renderer->cap_display, - x + cumulative_seg_width[seg], y, buf, - textcol); - } - - pos = ccrow_find_next_text_part(this, endpos); - } -} - - -/*----------------- cc_buffer_t methods --------------------------------*/ - -static int ccbuf_has_displayable(cc_buffer_t *this) -{ - int i; - int found = 0; - for (i = 0; !found && i < CC_ROWS; i++) { - if (this->rows[i].num_chars > 0) - found = 1; - } - return found; -} - - -static void ccbuf_add_char(cc_buffer_t *this, uint8_t c) -{ - cc_row_t *rowbuf = &this->rows[this->rowpos]; - int pos = rowbuf->pos; - int left_displayable = (pos > 0) && (pos <= rowbuf->num_chars); - -#if LOG_DEBUG > 2 - printf("cc_decoder: ccbuf_add_char: %c @ %d/%d\n", c, this->rowpos, pos); -#endif - - if (pos >= CC_COLUMNS) { - printf("cc_decoder: ccbuf_add_char: row buffer overflow\n"); - return; - } - - if (pos > rowbuf->num_chars) { - /* fill up to indented position with transparent spaces, if necessary */ - ccrow_fill_transp(rowbuf); - } - - /* midrow PAC attributes are applied only if there is no displayable */ - /* character to the immediate left. This makes the implementation rather */ - /* complicated, but this is what the EIA-608 standard specifies. :-( */ - if (rowbuf->pac_attr_chg && !rowbuf->attr_chg && !left_displayable) { - rowbuf->attr_chg = 1; - rowbuf->cells[pos].attributes = rowbuf->pac_attr; -#ifdef LOG_DEBUG - printf("cc_decoder: ccbuf_add_char: Applying midrow PAC.\n"); -#endif - } - - rowbuf->cells[pos].c = c; - rowbuf->cells[pos].midrow_attr = rowbuf->attr_chg; - rowbuf->pos++; - - if (rowbuf->num_chars < rowbuf->pos) - rowbuf->num_chars = rowbuf->pos; - - rowbuf->attr_chg = 0; - rowbuf->pac_attr_chg = 0; -} - - -static void ccbuf_set_cursor(cc_buffer_t *this, int row, int column, - int underline, int italics, int color) -{ - cc_row_t *rowbuf = &this->rows[row]; - cc_attribute_t attr; - - attr.italic = italics; - attr.underline = underline; - attr.foreground = color; - attr.background = BLACK; - - rowbuf->pac_attr = attr; - rowbuf->pac_attr_chg = 1; - - this->rowpos = row; - rowbuf->pos = column; - rowbuf->attr_chg = 0; -} - - -static void ccbuf_apply_attribute(cc_buffer_t *this, cc_attribute_t *attr) -{ - cc_row_t *rowbuf = &this->rows[this->rowpos]; - int pos = rowbuf->pos; - - rowbuf->attr_chg = 1; - rowbuf->cells[pos].attributes = *attr; - /* A midrow attribute always counts as a space */ - ccbuf_add_char(this, chartbl[(unsigned int) ' ']); -} - - -static void ccbuf_tab(cc_buffer_t *this, int tabsize) -{ - cc_row_t *rowbuf = &this->rows[this->rowpos]; - rowbuf->pos += tabsize; - if (rowbuf->pos > CC_COLUMNS) { -#ifdef LOG_DEBUG - printf("cc_decoder: ccbuf_tab: row buffer overflow\n"); -#endif - rowbuf->pos = CC_COLUMNS; - return; - } - /* tabs have no effect on pending PAC attribute changes */ -} - - -static void ccbuf_render(cc_renderer_t *renderer, cc_buffer_t *this) -{ - int row; - -#ifdef LOG_DEBUG - printf("cc_decoder: ccbuf_render\n"); -#endif - - for (row = 0; row < CC_ROWS; ++row) { - if (this->rows[row].num_chars > 0) - ccrow_render(renderer, &this->rows[row], row); - } -} - - -/*----------------- cc_memory_t methods --------------------------------*/ - -static void ccmem_clear(cc_memory_t *this) -{ -#ifdef LOG_DEBUG - printf("cc_decoder.c: ccmem_clear: Clearing CC memory\n"); -#endif - memset(this, 0, sizeof (cc_memory_t)); -} - - -static void ccmem_init(cc_memory_t *this) -{ - ccmem_clear(this); -} - - -static void ccmem_exit(cc_memory_t *this) -{ -/*FIXME: anything to deallocate?*/ -} - - -/*----------------- cc_renderer_t methods -------------------------------*/ - -static void cc_renderer_build_palette(cc_renderer_t *this) -{ - int i, j; - const colorinfo_t *cc_text = cc_text_palettes[this->cc_state->cc_cfg->cc_scheme]; - const uint8_t *cc_alpha = cc_alpha_palettes[this->cc_state->cc_cfg->cc_scheme]; - - memset(this->cc_palette, 0, sizeof (this->cc_palette)); - memset(this->cc_trans, 0, sizeof (this->cc_trans)); - for (i = 0; i < NUM_FG_COL; i++) { - /* background color */ - this->cc_palette[i * TEXT_PALETTE_SIZE + 1 + OSD_TEXT1] = - *(uint32_t *) &cc_text[i].bgcol; - /* background -> border */ - for (j = 2; j <= 5; j++) { - clut_t col = interpolate_color(cc_text[i].bgcol, - cc_text[i].bordercol, 4, j - 1); - this->cc_palette[i * TEXT_PALETTE_SIZE + j + OSD_TEXT1] = - *(uint32_t *) &col; - } - /* border color */ - this->cc_palette[i * TEXT_PALETTE_SIZE + 6 + OSD_TEXT1] = - *(uint32_t *) &cc_text[i].bordercol; - /* border -> foreground */ - for (j = 7; j <= 9; j++) { - clut_t col = interpolate_color(cc_text[i].bordercol, - cc_text[i].textcol, 3, j - 6); - this->cc_palette[i * TEXT_PALETTE_SIZE + j + OSD_TEXT1] = - *(uint32_t *) &col; - } - /* foreground color */ - this->cc_palette[i * TEXT_PALETTE_SIZE + 10 + OSD_TEXT1] = - *(uint32_t *) &cc_text[i].textcol; - - /* alpha values */ - for (j = 0; j <= 10; j++) - this->cc_trans[i * TEXT_PALETTE_SIZE + j + OSD_TEXT1] = cc_alpha[j]; - } -} - - -static int64_t cc_renderer_calc_vpts(cc_renderer_t *this, int64_t pts, - uint32_t ntsc_frame_offset) -{ - metronom_t *metronom = this->metronom; - int64_t vpts = metronom->got_spu_packet(metronom, pts); - return vpts + ntsc_frame_offset * NTSC_FRAME_DURATION; -} - - -/* returns true if a caption is on display */ -static int cc_renderer_on_display(cc_renderer_t *this) -{ - return this->displayed; -} - - -static void cc_renderer_hide_caption(cc_renderer_t *this, int64_t vpts) -{ - if (this->displayed) { - this->osd_renderer->hide(this->cap_display, vpts); - this->displayed = 0; - this->last_hide_vpts = vpts; - } -} - - -static void cc_renderer_show_caption(cc_renderer_t *this, cc_buffer_t *buf, - int64_t vpts) -{ -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: show\n"); -#endif - - if (this->displayed) { - cc_renderer_hide_caption(this, vpts); - printf("spucc: cc_renderer: show: OOPS - caption was already displayed!\n"); - } - - this->osd_renderer->clear(this->cap_display); - ccbuf_render(this, buf); - this->osd_renderer->set_position(this->cap_display, - this->x, - this->y); - vpts = MAX(vpts, this->last_hide_vpts); - this->osd_renderer->show(this->cap_display, vpts); - - this->displayed = 1; - this->display_vpts = vpts; -} - - -static void cc_renderer_free_osd_object(cc_renderer_t *this) -{ - /* hide and free old displayed caption object if necessary */ - if (this->cap_display) { - cc_renderer_hide_caption(this, this->display_vpts); - this->osd_renderer->free_object(this->cap_display); - this->cap_display = NULL; - } -} - - -static void cc_renderer_adjust_osd_object(cc_renderer_t *this) -{ - cc_renderer_free_osd_object(this); - -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: adjust_osd_object: creating %dx%d OSD object\n", - this->width, this->height); -#endif - - /* create display object */ - this->cap_display = this->osd_renderer->new_object(this->osd_renderer, - this->width, - this->height); - this->osd_renderer->set_palette(this->cap_display, this->cc_palette, - this->cc_trans); - this->osd_renderer->set_encoding(this->cap_display, "iso-8859-1"); -} - - -cc_renderer_t *cc_renderer_open(osd_renderer_t *osd_renderer, - metronom_t *metronom, cc_state_t *cc_state, - int video_width, int video_height) -{ - cc_renderer_t *this = (cc_renderer_t *) xine_xmalloc(sizeof (cc_renderer_t)); - - this->osd_renderer = osd_renderer; - this->metronom = metronom; - this->cc_state = cc_state; - cc_renderer_update_cfg(this, video_width, video_height); -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: open\n"); -#endif - return this; -} - - -void cc_renderer_close(cc_renderer_t *this_obj) -{ - cc_renderer_free_osd_object(this_obj); - free(this_obj); - -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: close\n"); -#endif -} - - -void cc_renderer_update_cfg(cc_renderer_t *this_obj, int video_width, - int video_height) -{ - int fontw, fonth; - int required_w, required_h; - - this_obj->video_width = video_width; - this_obj->video_height = video_height; - - /* fill in text palette */ - cc_renderer_build_palette(this_obj); - - /* calculate preferred captioning area, as per the EIA-608 standard */ - this_obj->x = this_obj->video_width * 10 / 100; - this_obj->y = this_obj->video_height * 10 / 100; - this_obj->width = this_obj->video_width * 80 / 100; - this_obj->height = this_obj->video_height * 80 / 100; - - /* find maximum text width and height for normal & italic captioning */ - /* font */ - get_font_metrics(this_obj->osd_renderer, this_obj->cc_state->cc_cfg->font, - this_obj->cc_state->cc_cfg->font_size, &fontw, &fonth); - this_obj->max_char_width = fontw; - this_obj->max_char_height = fonth; - get_font_metrics(this_obj->osd_renderer, this_obj->cc_state->cc_cfg->italic_font, - this_obj->cc_state->cc_cfg->font_size, &fontw, &fonth); - this_obj->max_char_width = MAX(fontw, this_obj->max_char_width); - this_obj->max_char_height = MAX(fonth, this_obj->max_char_height); -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: update config: max text extents: %d, %d\n", - this_obj->max_char_width, this_obj->max_char_height); -#endif - - /* need to adjust captioning area to accommodate font? */ - required_w = CC_COLUMNS * (this_obj->max_char_width + 1); - required_h = CC_ROWS * (this_obj->max_char_height + 1); - if (required_w > this_obj->width) { -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: update config: adjusting cap area width: %d\n", - required_w); -#endif - this_obj->width = required_w; - this_obj->x = (this_obj->video_width - required_w) / 2; - } - if (required_h > this_obj->height) { -#ifdef LOG_DEBUG - printf("spucc: cc_renderer: update config: adjusting cap area height: %d\n", - required_h); -#endif - this_obj->height = required_h; - this_obj->y = (this_obj->video_height - required_h) / 2; - } - - if (required_w <= this_obj->video_width && - required_h <= this_obj->video_height) { - this_obj->cc_state->can_cc = 1; - cc_renderer_adjust_osd_object(this_obj); - } - else { - this_obj->cc_state->can_cc = 0; - cc_renderer_free_osd_object(this_obj); - printf("spucc: required captioning area %dx%d exceeds screen %dx%d!\n" - " Captions disabled. Perhaps you should choose a smaller" - " font?\n", - required_w, required_h, this_obj->video_width, - this_obj->video_height); - } -} - - -/*----------------- cc_decoder_t methods --------------------------------*/ - -static void cc_set_channel(cc_decoder_t *this, int channel) -{ - (*this->active)->channel_no = channel; -#ifdef LOG_DEBUG - printf("cc_decoder: cc_set_channel: selecting channel %d\n", channel); -#endif -} - - -static cc_buffer_t *active_ccbuffer(cc_decoder_t *this) -{ - cc_memory_t *mem = *this->active; - return &mem->channel[mem->channel_no]; -} - - -static int cc_onscreen_displayable(cc_decoder_t *this) -{ - return ccbuf_has_displayable(&this->on_buf->channel[this->on_buf->channel_no]); -} - - -static void cc_hide_displayed(cc_decoder_t *this) -{ -#ifdef LOG_DEBUG - printf("cc_decoder: cc_hide_displayed\n"); -#endif - - if (cc_renderer_on_display(this->cc_state->renderer)) { - int64_t vpts = cc_renderer_calc_vpts(this->cc_state->renderer, this->pts, - this->f_offset); -#ifdef LOG_DEBUG - printf("cc_decoder: cc_hide_displayed: hiding caption %u at vpts %u\n", this->capid, vpts); -#endif - cc_renderer_hide_caption(this->cc_state->renderer, vpts); - } -} - - -static void cc_show_displayed(cc_decoder_t *this) -{ -#ifdef LOG_DEBUG - printf("cc_decoder: cc_show_displayed\n"); -#endif - - if (cc_onscreen_displayable(this)) { - int64_t vpts = cc_renderer_calc_vpts(this->cc_state->renderer, this->pts, - this->f_offset); -#ifdef LOG_DEBUG - printf("cc_decoder: cc_show_displayed: showing caption %u at vpts %u\n", this->capid, vpts); -#endif - this->capid++; - cc_renderer_show_caption(this->cc_state->renderer, - &this->on_buf->channel[this->on_buf->channel_no], - vpts); - } -} - - -static void cc_swap_buffers(cc_decoder_t *this) -{ - cc_memory_t *temp; - - /* hide caption in displayed memory */ - cc_hide_displayed(this); - -#ifdef LOG_DEBUG - printf("cc_decoder: cc_swap_buffers: swapping caption memory\n"); -#endif - temp = this->on_buf; - this->on_buf = this->off_buf; - this->off_buf = temp; - - /* show new displayed memory */ - cc_show_displayed(this); -} - -static void cc_decode_standard_char(cc_decoder_t *this, uint8_t c1, uint8_t c2) -{ - cc_buffer_t *buf = active_ccbuffer(this); - /* c1 always is a valid character */ - ccbuf_add_char(buf, chartbl[c1]); - /* c2 might not be a printable character, even if c1 was */ - if (c2 & 0x60) - ccbuf_add_char(buf, chartbl[c2]); -} - - -static void cc_decode_PAC(cc_decoder_t *this, int channel, - uint8_t c1, uint8_t c2) -{ - cc_buffer_t *buf; - int row, column = 0; - int underline, italics = 0, color; - - /* There is one invalid PAC code combination. Ignore it. */ - if (c1 == 0x10 && c2 > 0x5f) - return; - - cc_set_channel(this, channel); - buf = active_ccbuffer(this); - - row = rowdata[((c1 & 0x07) << 1) | ((c2 & 0x20) >> 5)]; - if (c2 & 0x10) { - column = ((c2 & 0x0e) >> 1) * 4; /* preamble indentation */ - color = WHITE; /* indented lines have white color */ - } - else if ((c2 & 0x0e) == 0x0e) { - italics = 1; /* italics, they are always white */ - color = WHITE; - } - else - color = (c2 & 0x0e) >> 1; - underline = c2 & 0x01; - -#ifdef LOG_DEBUG - printf("cc_decoder: cc_decode_PAC: row %d, col %d, ul %d, it %d, clr %d\n", - row, column, underline, italics, color); -#endif - - ccbuf_set_cursor(buf, row, column, underline, italics, color); -} - - -static void cc_decode_ext_attribute(cc_decoder_t *this, int channel, - uint8_t c1, uint8_t c2) -{ - cc_set_channel(this, channel); -} - - -static void cc_decode_special_char(cc_decoder_t *this, int channel, - uint8_t c1, uint8_t c2) -{ - cc_buffer_t *buf; - - cc_set_channel(this, channel); - buf = active_ccbuffer(this); -#ifdef LOG_DEBUG - printf("cc_decoder: cc_decode_special_char: Mapping %x to %x\n", c2, specialchar[c2 & 0xf]); -#endif - ccbuf_add_char(buf, specialchar[c2 & 0xf]); -} - - -static void cc_decode_midrow_attr(cc_decoder_t *this, int channel, - uint8_t c1, uint8_t c2) -{ - cc_buffer_t *buf; - cc_attribute_t attr; - - cc_set_channel(this, channel); - buf = active_ccbuffer(this); - if (c2 < 0x2e) { - attr.italic = 0; - attr.foreground = (c2 & 0xe) >> 1; - } - else { - attr.italic = 1; - attr.foreground = WHITE; - } - attr.underline = c2 & 0x1; - attr.background = BLACK; -#ifdef LOG_DEBUG - printf("cc_decoder: cc_decode_midrow_attr: attribute %x\n", c2); - printf("cc_decoder: cc_decode_midrow_attr: ul %d, it %d, clr %d\n", - attr.underline, attr.italic, attr.foreground); -#endif - - ccbuf_apply_attribute(buf, &attr); -} - - -static void cc_decode_misc_control_code(cc_decoder_t *this, int channel, - uint8_t c1, uint8_t c2) -{ -#ifdef LOG_DEBUG - printf("cc_decoder: decode_misc: decoding %x %x\n", c1, c2); -#endif - - cc_set_channel(this, channel); - - switch (c2) { /* 0x20 <= c2 <= 0x2f */ - - case 0x20: /* RCL */ - break; - - case 0x21: /* backspace */ -#ifdef LOG_DEBUG - printf("cc_decoder: backspace\n"); -#endif - break; - - case 0x24: /* DER */ - break; - - case 0x25: /* RU2 */ - break; - - case 0x26: /* RU3 */ - break; - - case 0x27: /* RU4 */ - break; - - case 0x28: /* FON */ - break; - - case 0x29: /* RDC */ - break; - - case 0x2a: /* TR */ - break; - - case 0x2b: /* RTD */ - break; - - case 0x2c: /* EDM - erase displayed memory */ - cc_hide_displayed(this); - ccmem_clear(this->on_buf); - break; - - case 0x2d: /* carriage return */ - break; - - case 0x2e: /* ENM - erase non-displayed memory */ - ccmem_clear(this->off_buf); - break; - - case 0x2f: /* EOC - swap displayed and non displayed memory */ - cc_swap_buffers(this); - break; - } -} - - -static void cc_decode_tab(cc_decoder_t *this, int channel, - uint8_t c1, uint8_t c2) -{ - cc_buffer_t *buf; - - cc_set_channel(this, channel); - buf = active_ccbuffer(this); - ccbuf_tab(buf, c2 & 0x3); -} - - -static void cc_decode_EIA608(cc_decoder_t *this, uint16_t data) -{ - uint8_t c1 = data & 0x7f; - uint8_t c2 = (data >> 8) & 0x7f; - -#if LOG_DEBUG >= 3 - printf("decoding %x %x\n", c1, c2); -#endif - - if (c1 & 0x60) { /* normal character, 0x20 <= c1 <= 0x7f */ - cc_decode_standard_char(this, c1, c2); - } - else if (c1 & 0x10) { /* control code or special character */ - /* 0x10 <= c1 <= 0x1f */ - int channel = (c1 & 0x08) >> 3; - c1 &= ~0x08; - - /* control sequences are often repeated. In this case, we should */ - /* evaluate it only once. */ - if (data != this->lastcode) { - - if (c2 & 0x40) { /* preamble address code: 0x40 <= c2 <= 0x7f */ - cc_decode_PAC(this, channel, c1, c2); - } - else { - switch (c1) { - - case 0x10: /* extended background attribute code */ - cc_decode_ext_attribute(this, channel, c1, c2); - break; - - case 0x11: /* attribute or special character */ - if ((c2 & 0x30) == 0x30) { /* special char: 0x30 <= c2 <= 0x3f */ - cc_decode_special_char(this, channel, c1, c2); - } - else if (c2 & 0x20) { /* midrow attribute: 0x20 <= c2 <= 0x2f */ - cc_decode_midrow_attr(this, channel, c1, c2); - } - break; - - case 0x14: /* possibly miscellaneous control code */ - cc_decode_misc_control_code(this, channel, c1, c2); - break; - - case 0x17: /* possibly misc. control code TAB offset */ - /* 0x21 <= c2 <= 0x23 */ - if (c2 >= 0x21 && c2 <= 0x23) { - cc_decode_tab(this, channel, c1, c2); - } - break; - } - } - } - } - - this->lastcode = data; -} - - -void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len, - int64_t pts) -{ - /* The first number may denote a channel number. I don't have the - * EIA-708 standard, so it is hard to say. - * From what I could figure out so far, the general format seems to be: - * - * repeat - * - * 0xfe starts 2 byte sequence of unknown purpose. It might denote - * field #2 in line 21 of the VBI. We'll ignore it for the - * time being. - * - * 0xff starts 2 byte EIA-608 sequence, field #1 in line 21 of the VBI. - * Followed by a 3-code triplet that starts either with 0xff or - * 0xfe. In either case, the following triplet needs to be ignored - * for line 21, field 1. - * - * 0x00 is padding, followed by 2 more 0x00. - * - * 0x01 always seems to appear at the beginning, always seems to - * be followed by 0xf8, 8-bit number. - * The lower 7 bits of this 8-bit number seem to denote the - * number of code triplets that follow. - * The most significant bit denotes whether the Line 21 field 1 - * captioning information is at odd or even triplet offsets from this - * beginning triplet. 1 denotes odd offsets, 0 denotes even offsets. - * - * Most captions are encoded with odd offsets, so this is what we - * will assume. - * - * until end of packet - */ - uint8_t *current = buffer; - uint32_t curbytes = 0; - uint8_t data1, data2; - uint8_t cc_code; - int odd_offset = 1; - - this->f_offset = 0; - this->pts = pts; - -#if LOG_DEBUG >= 2 - printf("libspucc: decode_cc: got pts %u\n", pts); - { - uint8_t *cur_d = buffer; - printf("libspucc: decode_cc: codes: "); - while (cur_d < buffer + buf_len) { - printf("0x%0x ", *cur_d++); - } - printf("\n"); - } -#endif - - while (curbytes < buf_len) { - int skip = 2; - - cc_code = *current++; - curbytes++; - - if (buf_len - curbytes < 2) { -#ifdef LOG_DEBUG - fprintf(stderr, "Not enough data for 2-byte CC encoding\n"); -#endif - break; - } - - data1 = *current; - data2 = *(current + 1); - - switch (cc_code) { - case 0xfe: - /* expect 2 byte encoding (perhaps CC3, CC4?) */ - /* ignore for time being */ - skip = 2; - break; - - case 0xff: - /* expect EIA-608 CC1/CC2 encoding */ - if (good_parity(data1 | (data2 << 8))) { - cc_decode_EIA608(this, data1 | (data2 << 8)); - this->f_offset++; - } - skip = 5; - break; - - case 0x00: - /* This seems to be just padding */ - skip = 2; - break; - - case 0x01: - odd_offset = data2 & 0x80; - if (odd_offset) - skip = 2; - else - skip = 5; - break; - - default: -#ifdef LOG_DEBUG - fprintf(stderr, "Unknown CC encoding: %x\n", cc_code); -#endif - skip = 2; - break; - } - current += skip; - curbytes += skip; - } -} - - - -cc_decoder_t *cc_decoder_open(cc_state_t *cc_state) -{ - cc_decoder_t *this = (cc_decoder_t *) xine_xmalloc(sizeof (cc_decoder_t)); - /* configfile stuff */ - this->cc_state = cc_state; - - ccmem_init(&this->buffer[0]); - ccmem_init(&this->buffer[1]); - this->on_buf = &this->buffer[0]; - this->off_buf = &this->buffer[1]; - this->active = &this->off_buf; - - this->lastcode = 0; - this->capid = 0; - - this->pts = this->f_offset = 0; - -#ifdef LOG_DEBUG - printf("spucc: cc_decoder_open\n"); -#endif - return this; -} - - -void cc_decoder_close(cc_decoder_t *this) -{ - ccmem_exit(&this->buffer[0]); - ccmem_exit(&this->buffer[1]); - - free(this); - -#ifdef LOG_DEBUG - printf("spucc: cc_decoder_close\n"); -#endif -} - - -/*--------------- initialization methods --------------------------*/ - -void cc_decoder_init(void) -{ - build_parity_table(); - build_char_table(); -} - diff --git a/src/libspucc/cc_decoder.h b/src/libspucc/cc_decoder.h deleted file mode 100644 index 3924bb8be..000000000 --- a/src/libspucc/cc_decoder.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * Copyright (C) Christian Vogler - * cvogler@gradient.cis.upenn.edu - December 2001 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stuff needed to provide closed captioning decoding and display - * - * Some small bits and pieces of the EIA-608 captioning decoder were - * adapted from CCDecoder 0.9.1 by Mike Baker. The latest version is - * available at http://sourceforge.net/projects/ccdecoder/. - */ - -typedef struct cc_decoder_s cc_decoder_t; -typedef struct cc_renderer_s cc_renderer_t; - -#define NUM_CC_PALETTES 2 -static const char *const cc_schemes[NUM_CC_PALETTES + 1] = { - "White/Gray/Translucent", - "White/Black/Solid", - NULL -}; - -#define CC_FONT_MAX 256 - -typedef struct cc_config_s { - int cc_enabled; /* true if closed captions are enabled */ - char font[CC_FONT_MAX]; /* standard captioning font & size */ - int font_size; - char italic_font[CC_FONT_MAX]; /* italic captioning font & size */ - int center; /* true if captions should be centered */ - /* according to text width */ - int cc_scheme; /* which captioning scheme to use */ - - int config_version; /* the decoder should be updated when this is increased */ -} cc_config_t; - -typedef struct spucc_class_s { - spu_decoder_class_t spu_class; - cc_config_t cc_cfg; -} spucc_class_t; - -typedef struct cc_state_s { - cc_config_t *cc_cfg; - /* the following variables are not controlled by configuration files; they */ - /* are intrinsic to the properties of the configuration options and the */ - /* currently played video */ - int can_cc; /* true if captions can be displayed */ - /* (e.g., font fits on screen) */ - cc_renderer_t *renderer; /* closed captioning renderer */ -} cc_state_t; - -cc_decoder_t *cc_decoder_open(cc_state_t *cc_state); -void cc_decoder_close(cc_decoder_t *this_obj); -void cc_decoder_init(void); - -void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len, - int64_t pts); - -/* Instantiates a new closed captioning renderer. */ -cc_renderer_t *cc_renderer_open(osd_renderer_t *osd_renderer, - metronom_t *metronom, cc_state_t *cc_state, - int video_width, int video_height); - -/* Destroys a closed captioning renderer. */ -void cc_renderer_close(cc_renderer_t *this_obj); - -/* Updates the renderer configuration variables */ -void cc_renderer_update_cfg(cc_renderer_t *this_obj, int video_width, - int video_height); - diff --git a/src/libspucc/xine_cc_decoder.c b/src/libspucc/xine_cc_decoder.c deleted file mode 100644 index e8a02a996..000000000 --- a/src/libspucc/xine_cc_decoder.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * closed caption spu decoder. receive data by events. - */ - -#include -#include -#include - -#include -#include -#include -#include "cc_decoder.h" - -/* -#define LOG_DEBUG 1 -*/ - -typedef struct spucc_decoder_s { - spu_decoder_t spu_decoder; - - xine_stream_t *stream; - - /* closed captioning decoder state */ - cc_decoder_t *ccdec; - /* true if ccdec has been initialized */ - int cc_open; - - /* closed captioning decoder configuration and intrinsics */ - cc_state_t cc_state; - /* this is to detect configuration changes */ - int config_version; - - /* video dimensions captured in frame change events */ - int video_width; - int video_height; - - /* events will be sent here */ - xine_event_queue_t *queue; - -} spucc_decoder_t; - - -/*------------------- general utility functions ----------------------------*/ - -static void copy_str(char *d, const char *s, size_t maxbytes) -{ - strncpy(d, s, maxbytes - 1); - d[maxbytes - 1] = '\0'; -} - - -/*------------------- private methods --------------------------------------*/ - -static void spucc_update_intrinsics(spucc_decoder_t *this) -{ -#ifdef LOG_DEBUG - printf("spucc: update_intrinsics\n"); -#endif - - if (this->cc_open) - cc_renderer_update_cfg(this->cc_state.renderer, this->video_width, - this->video_height); -} - -static void spucc_do_close(spucc_decoder_t *this) -{ - if (this->cc_open) { -#ifdef LOG_DEBUG - printf("spucc: close\n"); -#endif - cc_decoder_close(this->ccdec); - cc_renderer_close(this->cc_state.renderer); - this->cc_open = 0; - } -} - -static void spucc_do_init (spucc_decoder_t *this) -{ - if (! this->cc_open) { -#ifdef LOG_DEBUG - printf("spucc: init\n"); -#endif - /* initialize caption renderer */ - this->cc_state.renderer = cc_renderer_open(this->stream->osd_renderer, - this->stream->metronom, - &this->cc_state, - this->video_width, - this->video_height); - spucc_update_intrinsics(this); - /* initialize CC decoder */ - this->ccdec = cc_decoder_open(&this->cc_state); - this->cc_open = 1; - } -} - - -/*----------------- configuration listeners --------------------------------*/ - -static void spucc_cfg_enable_change(void *this_gen, xine_cfg_entry_t *value) -{ - spucc_class_t *this = (spucc_class_t *) this_gen; - cc_config_t *cc_cfg = &this->cc_cfg; - - cc_cfg->cc_enabled = value->num_value; -#ifdef LOG_DEBUG - printf("spucc: closed captions are now %s.\n", cc_cfg->cc_enabled? - "enabled" : "disabled"); -#endif - cc_cfg->config_version++; -} - - -static void spucc_cfg_scheme_change(void *this_gen, xine_cfg_entry_t *value) -{ - spucc_class_t *this = (spucc_class_t *) this_gen; - cc_config_t *cc_cfg = &this->cc_cfg; - - cc_cfg->cc_scheme = value->num_value; -#ifdef LOG_DEBUG - printf("spucc: closed captioning scheme is now %s.\n", - cc_schemes[cc_cfg->cc_scheme]); -#endif - cc_cfg->config_version++; -} - - -static void spucc_font_change(void *this_gen, xine_cfg_entry_t *value) -{ - spucc_class_t *this = (spucc_class_t *) this_gen; - cc_config_t *cc_cfg = &this->cc_cfg; - char *font; - - if (strcmp(value->key, "subtitles.closedcaption.font") == 0) - font = cc_cfg->font; - else - font = cc_cfg->italic_font; - - copy_str(font, value->str_value, CC_FONT_MAX); -#ifdef LOG_DEBUG - printf("spucc: changing %s to font %s\n", value->key, font); -#endif - cc_cfg->config_version++; -} - - -static void spucc_num_change(void *this_gen, xine_cfg_entry_t *value) -{ - spucc_class_t *this = (spucc_class_t *) this_gen; - cc_config_t *cc_cfg = &this->cc_cfg; - int *num; - - if (strcmp(value->key, "subtitles.closedcaption.font_size") == 0) - num = &cc_cfg->font_size; - else - num = &cc_cfg->center; - - *num = value->num_value; -#ifdef LOG_DEBUG - printf("spucc: changing %s to %d\n", value->key, *num); -#endif - cc_cfg->config_version++; -} - - -static void spucc_register_cfg_vars(spucc_class_t *this, - config_values_t *xine_cfg) { - cc_config_t *cc_vars = &this->cc_cfg; - - cc_vars->cc_enabled = xine_cfg->register_bool(xine_cfg, - "subtitles.closedcaption.enabled", 0, - _("display closed captions in MPEG-2 streams"), - _("Closed Captions are subtitles mostly meant " - "to help the hearing impaired."), - 0, spucc_cfg_enable_change, this); - - cc_vars->cc_scheme = xine_cfg->register_enum(xine_cfg, - "subtitles.closedcaption.scheme", 0, - cc_schemes, - _("closed-captioning foreground/background scheme"), - _("Choose your favourite rendering of the closed " - "captions."), - 10, spucc_cfg_scheme_change, this); - - copy_str(cc_vars->font, - xine_cfg->register_string(xine_cfg, "subtitles.closedcaption.font", "cc", - _("standard closed captioning font"), - _("Choose the font for standard closed captions text."), - 20, spucc_font_change, this), - CC_FONT_MAX); - - copy_str(cc_vars->italic_font, - xine_cfg->register_string(xine_cfg, "subtitles.closedcaption.italic_font", "cci", - _("italic closed captioning font"), - _("Choose the font for italic closed captions text."), - 20, spucc_font_change, this), - CC_FONT_MAX); - - cc_vars->font_size = xine_cfg->register_num(xine_cfg, "subtitles.closedcaption.font_size", - 24, - _("closed captioning font size"), - _("Choose the font size for closed captions text."), - 10, spucc_num_change, this); - - cc_vars->center = xine_cfg->register_bool(xine_cfg, "subtitles.closedcaption.center", 1, - _("center-adjust closed captions"), - _("When enabled, closed captions will be positioned " - "by the center of the individual lines."), - 20, spucc_num_change, this); -} - - -/* called when the video frame size changes */ -static void spucc_notify_frame_change(spucc_decoder_t *this, - int width, int height) { -#ifdef LOG_DEBUG - printf("spucc: new frame size: %dx%d\n", width, height); -#endif - - this->video_width = width; - this->video_height = height; - spucc_update_intrinsics(this); -} - - -/*------------------- implementation of spudec interface -------------------*/ - -static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { - spucc_decoder_t *this = (spucc_decoder_t *) this_gen; - xine_event_t *event; - - while ((event = xine_event_get(this->queue))) { - switch (event->type) { - case XINE_EVENT_FRAME_FORMAT_CHANGE: - { - xine_format_change_data_t *frame_change = - (xine_format_change_data_t *)event->data; - - spucc_notify_frame_change(this, frame_change->width, - frame_change->height); - } - break; - } - xine_event_free(event); - } - - if (buf->decoder_flags & BUF_FLAG_PREVIEW) { - } else { - - if (this->cc_state.cc_cfg->config_version > this->config_version) { - spucc_update_intrinsics(this); - if (!this->cc_state.cc_cfg->cc_enabled) - spucc_do_close(this); - this->config_version = this->cc_state.cc_cfg->config_version; - } - - if (this->cc_state.cc_cfg->cc_enabled) { - if( !this->cc_open ) - spucc_do_init (this); - if(this->cc_state.can_cc) { - decode_cc(this->ccdec, buf->content, buf->size, - buf->pts); - } - } - } -} - -static void spudec_reset (spu_decoder_t *this_gen) { -} - -static void spudec_discontinuity (spu_decoder_t *this_gen) { -} - -static void spudec_dispose (spu_decoder_t *this_gen) { - spucc_decoder_t *this = (spucc_decoder_t *) this_gen; - - spucc_do_close(this); - xine_event_dispose_queue(this->queue); - free (this); -} - - -static spu_decoder_t *spudec_open_plugin (spu_decoder_class_t *class, xine_stream_t *stream) { - - spucc_decoder_t *this ; - - this = (spucc_decoder_t *) xine_xmalloc (sizeof (spucc_decoder_t)); - - this->spu_decoder.decode_data = spudec_decode_data; - this->spu_decoder.reset = spudec_reset; - this->spu_decoder.discontinuity = spudec_discontinuity; - this->spu_decoder.dispose = spudec_dispose; - this->spu_decoder.get_interact_info = NULL; - this->spu_decoder.set_button = NULL; - - this->stream = stream; - this->queue = xine_event_new_queue(stream); - this->cc_state.cc_cfg = &((spucc_class_t *)class)->cc_cfg; - this->config_version = 0; - this->cc_open = 0; - - cc_decoder_init(); - - return &this->spu_decoder; -} - -static void *init_spu_decoder_plugin (xine_t *xine, void *data) { - - spucc_class_t *this ; - - this = (spucc_class_t *) xine_xmalloc (sizeof (spucc_class_t)); - - this->spu_class.open_plugin = spudec_open_plugin; - this->spu_class.identifier = "spucc"; - this->spu_class.description = N_("closed caption decoder plugin"); - this->spu_class.dispose = default_spu_decoder_class_dispose; - - spucc_register_cfg_vars(this, xine->config); - this->cc_cfg.config_version = 0; - - return &this->spu_class; -} - -/* plugin catalog information */ -static uint32_t supported_types[] = { BUF_SPU_CC, 0 }; - -static const decoder_info_t spudec_info = { - supported_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_SPU_DECODER, 17, "spucc", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libspucmml/Makefile.am b/src/libspucmml/Makefile.am deleted file mode 100644 index 85f5dbcd9..000000000 --- a/src/libspucmml/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -xineplug_LTLIBRARIES = xineplug_decode_spucmml.la - -xineplug_decode_spucmml_la_SOURCES = xine_cmml_decoder.c -xineplug_decode_spucmml_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) diff --git a/src/libspucmml/xine_cmml_decoder.c b/src/libspucmml/xine_cmml_decoder.c deleted file mode 100644 index 6ce6d3f90..000000000 --- a/src/libspucmml/xine_cmml_decoder.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - */ - -#define LOG_MODULE "libspucmml" -#define LOG_VERBOSE -/* -#define LOG -*/ -#define LOG_OSD 0 -#define LOG_SCHEDULING 0 -#define LOG_WIDTH 0 - -#define SUB_BUFSIZE 1024 -#define SUB_MAX_TEXT 5 - -#include - -typedef enum { - SUBTITLE_SIZE_SMALL = 0, - SUBTITLE_SIZE_NORMAL, - SUBTITLE_SIZE_LARGE, - - SUBTITLE_SIZE_NUM /* number of values in enum */ -} subtitle_size; - - -typedef struct spucmml_class_s { - spu_decoder_class_t class; - char *src_encoding; /* encoding of subtitle file */ - xine_t *xine; - -} spucmml_class_t; - - -typedef struct cmml_anchor_s { - char *text; - char *href; -} cmml_anchor_t; - - -typedef struct spucmml_decoder_s { - spu_decoder_t spu_decoder; - - spucmml_class_t *class; - xine_stream_t *stream; - - xine_event_queue_t *event_queue; - - int lines; - char text[SUB_MAX_TEXT][SUB_BUFSIZE]; - - int cached_width; /* frame width */ - int cached_height; /* frame height */ - int64_t cached_img_duration; - int font_size; - int line_height; - int master_started; - int slave_started; - - char *font; /* subtitle font */ - subtitle_size subtitle_size; /* size of subtitles */ - int vertical_offset; - - osd_object_t *osd; - - cmml_anchor_t current_anchor; -} spucmml_decoder_t; - - -static void video_frame_format_change_callback (void *user_data, const xine_event_t *event); - - -static void update_font_size (spucmml_decoder_t *this) { - static int sizes[SUBTITLE_SIZE_NUM][4] = { - { 16, 16, 16, 20 }, /* SUBTITLE_SIZE_SMALL */ - { 16, 16, 20, 24 }, /* SUBTITLE_SIZE_NORMAL */ - { 16, 20, 24, 32 }, /* SUBTITLE_SIZE_LARGE */ - }; - - int *vec = sizes[this->subtitle_size]; - int y; - - if( this->cached_width >= 512 ) - this->font_size = vec[3]; - else if( this->cached_width >= 384 ) - this->font_size = vec[2]; - else if( this->cached_width >= 320 ) - this->font_size = vec[1]; - else - this->font_size = vec[0]; - - this->line_height = this->font_size + 10; - - y = this->cached_height - (SUB_MAX_TEXT * this->line_height) - 5; - - if(((y - this->vertical_offset) >= 0) && ((y - this->vertical_offset) <= this->cached_height)) - y -= this->vertical_offset; - - /* TODO: we should move this stuff below into another function */ - - if (this->osd) - this->stream->osd_renderer->free_object (this->osd); - - llprintf (LOG_OSD, - "pre new_object: osd=%p, osd_renderer=%p, width=%d, height=%d\n", - this->osd, - this->stream->osd_renderer, - this->cached_width, - SUB_MAX_TEXT * this->line_height); - - this->osd = this->stream->osd_renderer->new_object (this->stream->osd_renderer, - this->cached_width, SUB_MAX_TEXT * this->line_height); - - llprintf (LOG_OSD, "post new_object: osd is %p\n", this->osd); - - if(this->stream->osd_renderer) { - this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); - this->stream->osd_renderer->set_position (this->osd, 0, y); - } -} - -static int get_width(spucmml_decoder_t *this, char* text) { - size_t i=0; - int width=0,w,dummy; - char letter[2]={0, 0}; - - while (i<=strlen(text)) { - switch (text[i]) { - case '<': - if (!strncmp("", text+i, 3)) { - /*Do somethink to enable BOLD typeface*/ - i=i+3; - break; - } else if (!strncmp("", text+i, 3)) { - /*Do somethink to disable BOLD typeface*/ - i=i+4; - break; - } else if (!strncmp("", text+i, 3)) { - /*Do somethink to enable italics typeface*/ - i=i+3; - break; - } else if (!strncmp("", text+i, 3)) { - /*Do somethink to disable italics typeface*/ - i=i+4; - break; - } else if (!strncmp("", text+i, 3)) { - /*Do somethink to disable typing - fixme - no teststreams*/ - i=i+6; - break; - } else if (!strncmp("", text+i, 3)) { - /*Do somethink to enable typing - fixme - no teststreams*/ - i=i+7; - break; - } - default: - letter[0]=text[i]; - this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy); - width=width+w; - i++; - } - } - - llprintf(LOG_WIDTH, "get_width returning width of %d\n", width); - - return width; -} - -static void render_line(spucmml_decoder_t *this, int x, int y, char* text) { - size_t i=0; - int w,dummy; - char letter[2]={0,0}; - - while (i<=strlen(text)) { - letter[0]=text[i]; - this->stream->osd_renderer->render_text(this->osd, x, y, letter, OSD_TEXT1); - this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy); - x=x+w; - i++; - } -} - -static void draw_subtitle(spucmml_decoder_t *this, int64_t sub_start) { - - int line, y; - int font_size; - - this->stream->osd_renderer->filled_rect (this->osd, 0, 0, - this->cached_width-1, this->line_height * SUB_MAX_TEXT - 1, 0); - - y = (SUB_MAX_TEXT - this->lines) * this->line_height; - font_size = this->font_size; - this->stream->osd_renderer->set_encoding(this->osd, this->class->src_encoding); - - for (line=0; linelines; line++) { - int w,x; - while(1) { - w=get_width( this, this->text[line]); - x = (this->cached_width - w) / 2; - - if( w > this->cached_width && font_size > 16 ) { - font_size -= 4; - this->stream->osd_renderer->set_font (this->osd, this->font, font_size); - } else { - break; - } - } - render_line(this, x, y + line*this->line_height, this->text[line]); - } - - if( font_size != this->font_size ) - this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); - - - this->stream->osd_renderer->set_text_palette (this->osd, -1, OSD_TEXT1); - this->stream->osd_renderer->show (this->osd, sub_start); - - llprintf (LOG_SCHEDULING, - "spucmml: scheduling subtitle >%s< at %"PRId64", current time is %"PRId64"\n", - this->text[0], sub_start, - this->stream->xine->clock->get_current_time (this->stream->xine->clock)); -} - -static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { - - spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; - char *str; - - xml_node_t *packet_xml_root; - char * anchor_text = NULL; - - lprintf("CMML packet seen\n"); - - str = (char *) buf->content; - - /* parse the CMML */ - - xml_parser_init (str, strlen (str), XML_PARSER_CASE_INSENSITIVE); - if (xml_parser_build_tree(&packet_xml_root) != XML_PARSER_OK) { - lprintf ("warning: invalid XML packet detected in CMML track\n"); - return; - } - - if (strcasecmp(packet_xml_root->name, "head") == 0) { - /* found a ... packet: need to parse the title */ - - xml_node_t *title_node; - - /* iterate through children trying to find the title node */ - - for (title_node = packet_xml_root->child; title_node != NULL; title_node = title_node->next) { - - if (strcasecmp (title_node->name, "title") == 0) { - /* found a title node */ - - xine_event_t uevent; - char *title; - int title_len; - - title = title_node->data; - - if (title) - { - xine_ui_data_t data; - /* found a non-empty title */ - lprintf ("found title: \"%s\"\n", title); - - /* set xine meta-info */ - _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, strdup(title)); - - /* and push out a new event signifying the title update on the event - * queue */ - title_len = strlen(title) + 1; - memcpy(data.str, title, title_len); - data.str_len = title_len; - - uevent.type = XINE_EVENT_UI_SET_TITLE; - uevent.stream = this->stream; - uevent.data = &data; - uevent.data_length = sizeof(data); - xine_event_send(this->stream, &uevent); - } - } - } - } else if (strcasecmp(packet_xml_root->name, "clip") == 0) { - /* found a ... packet: search for the in it */ - xml_node_t *clip_node; - - /* iterate through each tag contained in the tag to look for */ - - for (clip_node = packet_xml_root->child; clip_node != NULL; clip_node = clip_node->next) { - - if (strcasecmp (clip_node->name, "a") == 0) { - xml_property_t *href_property; - - /* found the tag: grab its value and its href property */ - - if (clip_node->data) - anchor_text = strdup (clip_node->data); - - for (href_property = clip_node->props; href_property != NULL; href_property = href_property->next) { - if (strcasecmp (href_property->name, "href") == 0) { - /* found the href property */ - char *href = href_property->value; - - if (href) { - lprintf ("found href: \"%s\"\n", href); - this->current_anchor.href = strdup(href); - } - } - } - } - } - } - - /* finish here if we don't have to process any anchor text */ - if (!anchor_text) - return; - - /* how many lines does the anchor text take up? */ - this->lines=0; - { - int i = 0; - while (*anchor_text) { - if (*anchor_text == '\r' || *anchor_text == '\n') { - if (i) { - /* match a newline and there are chars on the current line ... */ - this->text[ this->lines ][i] = '\0'; - this->lines++; - i = 0; - } - } else { - /* found a normal (non-line-ending) character */ - this->text[ this->lines ][i] = *anchor_text; - if (itext[ this->lines ][i] = '\0'; - this->lines++; - } - } - - /* initialize decoder if needed */ - if( !this->cached_width || !this->cached_height || !this->cached_img_duration || !this->osd ) { - if( this->stream->video_out->status(this->stream->video_out, NULL, - &this->cached_width, &this->cached_height, &this->cached_img_duration )) { - if( this->cached_width && this->cached_height && this->cached_img_duration ) { - lprintf("this->stream->osd_renderer is %p\n", this->stream->osd_renderer); - } - } - } - - update_font_size (this); - - if( this->osd ) { - draw_subtitle(this, buf->pts); - return; - } else { - lprintf ("libspucmml: no osd\n"); - } - - return; -} - -static void video_frame_format_change_callback (void *user_data, const xine_event_t *event) -{ - /* this doesn't do anything for now: it's a start at attempting to display - * CMML clips which occur at 0 seconds into the track. see - * - * http://marc.theaimsgroup.com/?l=xine-devel&m=109202443013890&w=2 - * - * for a description of the problem. */ - - switch (event->type) { - case XINE_EVENT_FRAME_FORMAT_CHANGE: - lprintf("video_frame_format_change_callback called!\n"); - break; - default: - lprintf("video_frame_format_change_callback called with unknown event %d\n", event->type); - break; - } -} - -static void spudec_reset (spu_decoder_t *this_gen) { - spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; - - this->cached_width = this->cached_height = 0; -} - -static void spudec_discontinuity (spu_decoder_t *this_gen) { - /* do nothing */ -} - -static void spudec_dispose (spu_decoder_t *this_gen) { - spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; - - if (this->event_queue) - xine_event_dispose_queue (this->event_queue); - - if (this->osd) { - this->stream->osd_renderer->free_object (this->osd); - this->osd = NULL; - } - free(this); -} - -static void update_vertical_offset(void *this_gen, xine_cfg_entry_t *entry) -{ - spucmml_decoder_t *this = (spucmml_decoder_t *)this_gen; - - this->vertical_offset = entry->num_value; - update_font_size(this); -} - -static void update_osd_font(void *this_gen, xine_cfg_entry_t *entry) -{ - spucmml_decoder_t *this = (spucmml_decoder_t *)this_gen; - - this->font = entry->str_value; - - if( this->stream->osd_renderer ) - this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); -} - -static spu_decoder_t *spucmml_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { - - spucmml_class_t *class = (spucmml_class_t *)class_gen; - spucmml_decoder_t *this ; - - this = (spucmml_decoder_t *) xine_xmalloc (sizeof (spucmml_decoder_t)); - - this->spu_decoder.decode_data = spudec_decode_data; - this->spu_decoder.reset = spudec_reset; - this->spu_decoder.discontinuity = spudec_discontinuity; - this->spu_decoder.dispose = spudec_dispose; - this->spu_decoder.get_interact_info = NULL; - this->spu_decoder.set_button = NULL; - this->spu_decoder.dispose = spudec_dispose; - - this->class = class; - this->stream = stream; - - this->event_queue = xine_event_new_queue (this->stream); - xine_event_create_listener_thread (this->event_queue, - video_frame_format_change_callback, - this); - - this->font_size = 24; - this->subtitle_size = 1; - - this->font = class->xine->config->register_string(class->xine->config, - "subtitles.separate.font", - "sans", - _("font for external subtitles"), - NULL, 0, update_osd_font, this); - - this->vertical_offset = class->xine->config->register_num(class->xine->config, - "subtitles.separate.vertical_offset", - 0, - _("subtitle vertical offset (relative window size)"), - NULL, 0, update_vertical_offset, this); - - this->current_anchor.href = NULL; - - lprintf ("video_out is at %p\n", this->stream->video_out); - - return (spu_decoder_t *) this; -} - -static void update_src_encoding(void *this_gen, xine_cfg_entry_t *entry) -{ - spucmml_class_t *this = (spucmml_class_t *)this_gen; - - this->src_encoding = entry->str_value; - printf("libspucmml: spu_src_encoding = %s\n", this->src_encoding ); -} - -static void *init_spu_decoder_plugin (xine_t *xine, void *data) { - - spucmml_class_t *this ; - - this = (spucmml_class_t *) xine_xmalloc (sizeof (spucmml_class_t)); - - this->class.open_plugin = spucmml_class_open_plugin; - this->class.identifier = "spucmml"; - this->class.description = N_("CMML subtitle decoder plugin"); - this->class.dispose = default_spu_decoder_class_dispose; - - this->xine = xine; - - this->src_encoding = xine->config->register_string(xine->config, - "subtitles.separate.src_encoding", - "iso-8859-1", - _("encoding of subtitles"), - NULL, 10, update_src_encoding, this); - - return &this->class; -} - - -/* plugin catalog information */ -static uint32_t supported_types[] = { BUF_SPU_CMML, 0 }; - -static const decoder_info_t spudec_info = { - supported_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_SPU_DECODER, 17, "spucmml", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am deleted file mode 100644 index 337428652..000000000 --- a/src/libspudec/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav -AM_LDFLAGS = $(xineplug_ldflags) - -noinst_HEADERS = spudec.h - -xineplug_LTLIBRARIES = xineplug_decode_spu.la - -if WITH_EXTERNAL_DVDNAV -external_dvdnav_libs = $(DVDNAV_LIBS) -internal_dvdnav_sources = -else -external_dvdnav_libs = -internal_dvdnav_sources = nav_read.c -endif - -xineplug_decode_spu_la_SOURCES = $(internal_dvdnav_sources) spudec.c xine_spu_decoder.c -xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(external_dvdnav_libs) $(PTHREAD_LIBS) -xineplug_decode_spu_la_CFLAGS = $(AM_CFLAGS) $(DVDNAV_CFLAGS) diff --git a/src/libspudec/nav_read.c b/src/libspudec/nav_read.c deleted file mode 100644 index 5244bfdd6..000000000 --- a/src/libspudec/nav_read.c +++ /dev/null @@ -1 +0,0 @@ -#include "../input/libdvdnav/nav_read.c" diff --git a/src/libspudec/spudec.c b/src/libspudec/spudec.c deleted file mode 100644 index 13136a53f..000000000 --- a/src/libspudec/spudec.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Copyright (C) 2002-2004 the xine project - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * spu.c - converts DVD subtitles to an XPM image - * - * Mostly based on hard work by: - * - * Copyright (C) 2000 Samuel Hocevar - * and Michel Lespinasse - * - * Lots of rearranging by: - * Aaron Holtzman - * Thomas Mirlacher - * implemented reassembling - * cleaner implementation of SPU are saving - * overlaying (proof of concept for now) - * ... and yes, it works now with oms - * added tranparency (provided by the SPU hdr) - * changed structures for easy porting to MGAs DVD mode - * This file is part of xine - * This file was originally part of the OMS program. - * - * This program 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, or (at your option) - * any later version. - * - * This program 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "xine-engine/bswap.h" -#ifdef HAVE_DVDNAV -# include -# include -#else -# include "nav_read.h" -# include "nav_print.h" -#endif - -#include "spudec.h" - -/* -#define LOG_DEBUG 1 -#define LOG_BUTTON 1 -#define LOG_NAV 1 -*/ - -static void spudec_do_commands (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); -static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); -static void spudec_discover_clut (xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl); -#ifdef LOG_DEBUG -static void spudec_print_overlay( vo_overlay_t *overlay ); -#endif - -void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) { - uint8_t *p; - uint32_t packet_len; - uint32_t stream_id; - uint32_t header_len; - pci_t pci; - dsi_t dsi; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - - p = buf->content; - if (p[0] || p[1] || (p[2] != 1)) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec:spudec_decode_nav:nav demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); - return; - } - - packet_len = p[4] << 8 | p[5]; - stream_id = p[3]; - - header_len = 6; - p += header_len; - - if (stream_id == 0xbf) { /* Private stream 2 */ -/* int i; - * for(i=0;i<80;i++) { - * printf("%02x ",p[i]); - * } - * printf("\n p[0]=0x%02x\n",p[0]); - */ - if(p[0] == 0x00) { -#ifdef LOG_NAV - printf("libspudec:nav_PCI\n"); -#endif - navRead_PCI(&pci, p+1); -#ifdef LOG_NAV - printf("libspudec:nav:hli_ss=%u, hli_s_ptm=%u, hli_e_ptm=%u, btn_sl_e_ptm=%u pts=%lli\n", - pci.hli.hl_gi.hli_ss, - pci.hli.hl_gi.hli_s_ptm, - pci.hli.hl_gi.hli_e_ptm, - pci.hli.hl_gi.btn_se_e_ptm, - buf->pts); - printf("libspudec:nav:btn_sn/ofn=%u, btn_ns=%u, fosl_btnn=%u, foac_btnn=%u\n", - pci.hli.hl_gi.btn_ofn, pci.hli.hl_gi.btn_ns, - pci.hli.hl_gi.fosl_btnn, pci.hli.hl_gi.foac_btnn); - printf("btngr_ns %d\n", pci.hli.hl_gi.btngr_ns); - printf("btngr%d_dsp_ty 0x%02x\n", 1, pci.hli.hl_gi.btngr1_dsp_ty); - printf("btngr%d_dsp_ty 0x%02x\n", 2, pci.hli.hl_gi.btngr2_dsp_ty); - printf("btngr%d_dsp_ty 0x%02x\n", 3, pci.hli.hl_gi.btngr3_dsp_ty); - //navPrint_PCI(&pci); - //navPrint_PCI_GI(&pci.pci_gi); - //navPrint_NSML_AGLI(&pci.nsml_agli); - //navPrint_HLI(&pci.hli); - //navPrint_HL_GI(&pci.hli.hl_gi, & btngr_ns, & btn_ns); -#endif - } - - p += packet_len; - - /* We should now have a DSI packet. */ - /* We don't need anything from the DSI packet here. */ - if(p[6] == 0x01) { - packet_len = p[4] << 8 | p[5]; - p += 6; -#ifdef LOG_NAV - printf("NAV DSI packet\n"); -#endif - navRead_DSI(&dsi, p+1); - -// self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; -// self->vobu_length = self->dsi.dsi_gi.vobu_ea; - } - } - - /* NAV packets contain start and end presentation timestamps, which tell the - * application, when the highlight information in the NAV is supposed to be valid. - * We handle these timestamps only in a very stripped-down way: We keep a list - * of NAV packets (or better: the PCI part of them), tagged with a VPTS timestamp - * telling, when the NAV should be processed. However, we only enqueue a new node - * into this list, when we receive new highlight information during an already - * showing menu. This happens very rarerly on common DVDs, so it is of low impact. - * And we only check for processing of queued entries at some prominent - * locations in this SPU decoder. Since presentation timestamps rarely solve a real - * purpose on most DVDs, this is ok compared to the full-blown solution, which would - * require a separate thread managing the queue all the time. */ - pthread_mutex_lock(&this->nav_pci_lock); - switch (pci.hli.hl_gi.hli_ss) { - case 0: - /* No Highlight information for this VOBU */ - if ( this->pci_cur.pci.hli.hl_gi.hli_ss == 1) { - /* Hide menu spu between menus */ -#ifdef LOG_BUTTON - printf("libspudec:nav:SHOULD HIDE SPU here\n"); -#endif - if( this->menu_handle < 0 ) { - this->menu_handle = ovl_manager->get_handle(ovl_manager,1); - } - if( this->menu_handle >= 0 ) { - this->event.object.handle = this->menu_handle; - this->event.event_type = OVERLAY_EVENT_HIDE; - /* hide menu right now */ - this->event.vpts = 0; - ovl_manager->add_event(ovl_manager, (void *)&this->event); - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: No video_overlay handles left for menu\n"); - } - } - spudec_clear_nav_list(this); - xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); - /* incoming SPUs will be plain subtitles */ - this->event.object.object_type = 0; - if (this->button_filter) { - /* we possibly had buttons before, so we update the UI info */ - xine_event_t event; - xine_ui_data_t data; - - event.type = XINE_EVENT_UI_NUM_BUTTONS; - event.data = &data; - event.data_length = sizeof(data); - data.num_buttons = 0; - - xine_event_send(this->stream, &event); - } - this->button_filter=0; - - break; - case 1: - /* All New Highlight information for this VOBU */ - if (this->pci_cur.pci.hli.hl_gi.hli_ss != 0 && - pci.hli.hl_gi.hli_s_ptm > this->pci_cur.pci.hli.hl_gi.hli_s_ptm) { - pci_node_t *node = &this->pci_cur; -#ifdef LOG_DEBUG - printf("libspudec: allocating new PCI node for hli_s_ptm %d\n", pci.hli.hl_gi.hli_s_ptm); -#endif - /* append PCI at the end of the list */ - while (node->next) node = node->next; - node->next = (pci_node_t *)xine_xmalloc(sizeof(pci_node_t)); - node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm); - node->next->next = NULL; - xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t)); - } else { - spudec_clear_nav_list(this); - /* menu ahead, remember PCI for later use */ - xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); - spudec_process_nav(this); - } - break; - case 2: - /* Use Highlight information from previous VOBU */ - if (this->pci_cur.next) { - /* apply changes to last enqueued NAV */ - pci_node_t *node = this->pci_cur.next; - while (node->next) node = node->next; - node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - spudec_update_nav(this); - } else { - this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - } - break; - case 3: - /* Use Highlight information from previous VOBU except commands, which come from this VOBU */ - if (this->pci_cur.next) { - /* apply changes to last enqueued NAV */ - pci_node_t *node = this->pci_cur.next; - while (node->next) node = node->next; - node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - /* FIXME: Add command copying here */ - spudec_update_nav(this); - } else { - this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; - this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; - this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; - /* FIXME: Add command copying here */ - } - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec: unknown pci.hli.hl_gi.hli_ss = %d\n", pci.hli.hl_gi.hli_ss ); - break; - } - pthread_mutex_unlock(&this->nav_pci_lock); - return; -} - -void spudec_clear_nav_list(spudec_decoder_t *this) -{ - while (this->pci_cur.next) { - pci_node_t *node = this->pci_cur.next->next; - free(this->pci_cur.next); - this->pci_cur.next = node; - } - /* invalidate current timestamp */ - this->pci_cur.pci.hli.hl_gi.hli_s_ptm = (uint32_t)-1; -} - -void spudec_update_nav(spudec_decoder_t *this) -{ - metronom_clock_t *clock = this->stream->xine->clock; - - if (this->pci_cur.next && this->pci_cur.next->vpts <= clock->get_current_time(clock)) { - pci_node_t *node = this->pci_cur.next; - xine_fast_memcpy(&this->pci_cur, this->pci_cur.next, sizeof(pci_node_t)); - spudec_process_nav(this); - free(node); - } -} - -void spudec_process_nav(spudec_decoder_t *this) -{ - /* incoming SPUs will be menus */ - this->event.object.object_type = 1; - if (!this->button_filter) { - /* we possibly entered a menu, so we update the UI button info */ - xine_event_t event; - xine_ui_data_t data; - - event.type = XINE_EVENT_UI_NUM_BUTTONS; - event.data = &data; - event.data_length = sizeof(data); - data.num_buttons = this->pci_cur.pci.hli.hl_gi.btn_ns; - - xine_event_send(this->stream, &event); - } - this->button_filter=1; -} - -void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len) -{ -#ifdef LOG_DEBUG - printf ("libspudec: seq->complete = %d\n", seq->complete); - printf("libspudec:1: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", - seq->ra_offs, - seq->seq_len, - seq->buf_len, - seq->buf); -#endif - if (seq->complete) { - seq->seq_len = (((uint32_t)pkt_data[0])<<8) | pkt_data[1]; - seq->cmd_offs = (((uint32_t)pkt_data[2])<<8) | pkt_data[3]; - if (seq->cmd_offs >= seq->seq_len) { - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); - seq->broken = 1; - } - if (seq->buf_len < seq->seq_len) { - seq->buf_len = seq->seq_len; -#ifdef LOG_DEBUG - printf ("spu: MALLOC1: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); -#endif - if (seq->buf) { - free(seq->buf); - seq->buf = NULL; - } - seq->buf = malloc(seq->buf_len); -#ifdef LOG_DEBUG - printf ("spu: MALLOC2: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); -#endif - - } - seq->ra_offs = 0; - -#ifdef LOG_DEBUG - printf ("spu: buf_len: %d\n", seq->buf_len); - printf ("spu: cmd_off: %d\n", seq->cmd_offs); -#endif - } - -#ifdef LOG_DEBUG - printf("libspudec:2: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", - seq->ra_offs, - seq->seq_len, - seq->buf_len, - seq->buf); -#endif - if (seq->ra_offs < seq->seq_len) { - if (seq->ra_offs + pkt_len > seq->seq_len) - pkt_len = seq->seq_len - seq->ra_offs; - memcpy (seq->buf + seq->ra_offs, pkt_data, pkt_len); - seq->ra_offs += pkt_len; - } else { - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); - seq->broken = 1; - } - - if (seq->ra_offs == seq->seq_len) { - seq->finished = 0; - seq->complete = 1; - return; /* sequence ready */ - } - seq->complete = 0; - return; -} - -void spudec_process (spudec_decoder_t *this, int stream_id) { - spudec_seq_t *cur_seq; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - int pending = 1; - cur_seq = &this->spudec_stream_state[stream_id].ra_seq; - -#ifdef LOG_DEBUG - printf ("spu: Found SPU from stream %d pts=%lli vpts=%lli\n",stream_id, - this->spudec_stream_state[stream_id].pts, - this->spudec_stream_state[stream_id].vpts); -#endif - this->state.cmd_ptr = cur_seq->buf + cur_seq->cmd_offs; - this->state.modified = 1; /* Only draw picture if = 1 on first event of SPU */ - this->state.visible = OVERLAY_EVENT_SHOW; - this->state.forced_display = 0; /* 0 - No value, 1 - Forced Display. */ - this->state.delay = 0; - cur_seq->finished=0; - - do { - if (!(cur_seq->finished) ) { - pci_node_t *node; - - /* spu_channel is now set based on whether we are in the menu or not. */ - /* Bit 7 is set if only forced display SPUs should be shown */ - if ( (this->stream->spu_channel & 0x1f) != stream_id ) { -#ifdef LOG_DEBUG - printf ("spu: Dropping SPU channel %d. Not selected stream_id\n", stream_id); -#endif - return; - } - /* parse SPU command sequence, this will update forced_display, so it must come - * before the check for it */ - spudec_do_commands(this->stream->xine, &this->state, cur_seq, &this->overlay); - /* FIXME: Check for Forced-display or subtitle stream - * For subtitles, open event. - * For menus, store it for later. - */ - if (cur_seq->broken) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); - cur_seq->broken = 0; - return; - } - if ( (this->state.forced_display == 0) && (this->stream->spu_channel & 0x80) ) { -#ifdef LOG_DEBUG - printf ("spu: Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id); -#endif - return; - } - -#ifdef LOG_DEBUG - spudec_print_overlay( &this->overlay ); - printf ("spu: forced display:%s\n", this->state.forced_display ? "Yes" : "No" ); -#endif - pthread_mutex_lock(&this->nav_pci_lock); - /* search for a PCI that matches this SPU's PTS */ - for (node = &this->pci_cur; node; node = node->next) - if (node->pci.hli.hl_gi.hli_s_ptm == this->spudec_stream_state[stream_id].pts) - break; - if (node) { - if (this->state.visible == OVERLAY_EVENT_HIDE) { - /* menus are hidden via nav packet decoding, not here */ - /* FIXME: James is not sure about this solution and may want to look this over. - * I'm commiting it, because I haven't found a disc it breaks, but it fixes - * some instead. Michael Roitzsch */ - pthread_mutex_unlock(&this->nav_pci_lock); - continue; - } - if (node->pci.hli.hl_gi.fosl_btnn > 0) { - xine_event_t event; - - this->buttonN = node->pci.hli.hl_gi.fosl_btnn; - event.type = XINE_EVENT_INPUT_BUTTON_FORCE; - event.stream = this->stream; - event.data = &this->buttonN; - event.data_length = sizeof(this->buttonN); - xine_event_send(this->stream, &event); - } -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec:Full Overlay\n"); -#endif - if (!spudec_copy_nav_to_overlay(this->stream->xine, - &node->pci, this->state.clut, - this->buttonN, 0, &this->overlay, &this->overlay)) { - /* current button does not exist -> use another one */ - xine_event_t event; - - if (this->buttonN > node->pci.hli.hl_gi.btn_ns) - this->buttonN = node->pci.hli.hl_gi.btn_ns; - else - this->buttonN = 1; - event.type = XINE_EVENT_INPUT_BUTTON_FORCE; - event.stream = this->stream; - event.data = &this->buttonN; - event.data_length = sizeof(this->buttonN); - xine_event_send(this->stream, &event); - spudec_copy_nav_to_overlay(this->stream->xine, - &node->pci, this->state.clut, - this->buttonN, 0, &this->overlay, &this->overlay); - } - } else { - /* Subtitle and not a menu button */ - int i; - for (i = 0;i < 4; i++) { - this->overlay.hili_color[i] = this->overlay.color[i]; - this->overlay.hili_trans[i] = this->overlay.trans[i]; - } - } - pthread_mutex_unlock(&this->nav_pci_lock); - - if ((this->state.modified) ) { - spudec_draw_picture(this->stream->xine, &this->state, cur_seq, &this->overlay); - } - - if (this->state.need_clut) { - spudec_discover_clut(this->stream->xine, &this->state, &this->overlay); - } - - if (this->state.vobsub) { - int width, height; - int64_t duration; - - /* - * vobsubs are usually played with a scaled-down stream (not full DVD - * resolution), therefore we should try to realign it. - */ - - this->stream->video_out->status(this->stream->video_out, NULL, - &width, &height, &duration ); - - this->overlay.x = (width - this->overlay.width) / 2; - this->overlay.y = height - this->overlay.height; - } - - /* Subtitle */ - if( this->menu_handle < 0 ) { - this->menu_handle = ovl_manager->get_handle(ovl_manager,1); - } - - if( this->menu_handle < 0 ) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec: No video_overlay handles left for menu\n"); - return; - } - this->event.object.handle = this->menu_handle; - this->event.object.pts = this->spudec_stream_state[stream_id].pts; - - xine_fast_memcpy(this->event.object.overlay, - &this->overlay, - sizeof(vo_overlay_t)); - this->overlay.rle=NULL; - /* For force display menus */ - //if ( !(this->state.visible) ) { - // this->state.visible = OVERLAY_EVENT_SHOW; - //} - - this->event.event_type = this->state.visible; - /* - printf("spu event %d handle: %d vpts: %lli\n", this->event.event_type, - this->event.object.handle, this->event.vpts ); - */ - - this->event.vpts = this->spudec_stream_state[stream_id].vpts+(this->state.delay*1000); - - /* Keep all the events in the correct order. */ - /* This corrects for errors during estimation around discontinuity */ - if( this->event.vpts < this->last_event_vpts ) { - this->event.vpts = this->last_event_vpts + 1; - } - this->last_event_vpts = this->event.vpts; - -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", - this->event.event_type, - this->stream->xine->clock->get_current_time(this->stream->xine->clock), - this->event.vpts); -#endif - ovl_manager->add_event(ovl_manager, (void *)&this->event); - } else { - pending = 0; - } - } while (pending); - -} - -#define CMD_SPU_FORCE_DISPLAY 0x00 -#define CMD_SPU_SHOW 0x01 -#define CMD_SPU_HIDE 0x02 -#define CMD_SPU_SET_PALETTE 0x03 -#define CMD_SPU_SET_ALPHA 0x04 -#define CMD_SPU_SET_SIZE 0x05 -#define CMD_SPU_SET_PXD_OFFSET 0x06 -#define CMD_SPU_WIPE 0x07 /* Not currently implemented */ -#define CMD_SPU_EOF 0xff - -static void spudec_do_commands(xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) -{ - uint8_t *buf = state->cmd_ptr; - uint8_t *next_seq; - int32_t param_length; - -#ifdef LOG_DEBUG - printf ("spu: SPU DO COMMANDS\n"); -#endif - - state->delay = (buf[0] << 8) + buf[1]; -#ifdef LOG_DEBUG - printf ("spu: \tdelay=%d\n",state->delay); -#endif - next_seq = seq->buf + (buf[2] << 8) + buf[3]; - buf += 4; -#ifdef LOG_DEBUG - printf ("spu: \tnext_seq=%d\n",next_seq - seq->buf); -#endif - -/* if next equals current, this is the last one - */ - if (state->cmd_ptr >= next_seq) - next_seq = seq->buf + seq->seq_len; /* allow to run until end */ - - state->cmd_ptr = next_seq; - - while (buf < next_seq && *buf != CMD_SPU_EOF) { - switch (*buf) { - case CMD_SPU_SHOW: /* show subpicture */ -#ifdef LOG_DEBUG - printf ("spu: \tshow subpicture\n"); -#endif - state->visible = OVERLAY_EVENT_SHOW; - buf++; - break; - - case CMD_SPU_HIDE: /* hide subpicture */ -#ifdef LOG_DEBUG - printf ("spu: \thide subpicture\n"); -#endif - state->visible = OVERLAY_EVENT_HIDE; - buf++; - break; - - case CMD_SPU_SET_PALETTE: { /* CLUT */ - spudec_clut_t *clut = (spudec_clut_t *) (buf+1); - - state->cur_colors[3] = clut->entry0; - state->cur_colors[2] = clut->entry1; - state->cur_colors[1] = clut->entry2; - state->cur_colors[0] = clut->entry3; - -/* This is a bit out of context for now */ - ovl->color[3] = state->clut[clut->entry0]; - ovl->color[2] = state->clut[clut->entry1]; - ovl->color[1] = state->clut[clut->entry2]; - ovl->color[0] = state->clut[clut->entry3]; - -#ifdef LOG_DEBUG - printf ("spu: \tclut [%x %x %x %x]\n", - ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); - printf ("spu: \tclut base [%x %x %x %x]\n", - clut->entry0, clut->entry1, clut->entry2, clut->entry3); -#endif - state->modified = 1; - buf += 3; - break; - } - case CMD_SPU_SET_ALPHA: { /* transparency palette */ - spudec_clut_t *trans = (spudec_clut_t *) (buf+1); -/* This should go into state for now */ - - ovl->trans[3] = trans->entry0; - ovl->trans[2] = trans->entry1; - ovl->trans[1] = trans->entry2; - ovl->trans[0] = trans->entry3; - -#ifdef LOG_DEBUG - printf ("spu: \ttrans [%d %d %d %d]\n", - ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); -#endif - state->modified = 1; - buf += 3; - break; - } - - case CMD_SPU_SET_SIZE: /* image coordinates */ -/* state->o_left = (buf[1] << 4) | (buf[2] >> 4); - state->o_right = (((buf[2] & 0x0f) << 8) | buf[3]); - - state->o_top = (buf[4] << 4) | (buf[5] >> 4); - state->o_bottom = (((buf[5] & 0x0f) << 8) | buf[6]); - */ - ovl->x = (buf[1] << 4) | (buf[2] >> 4); - ovl->y = (buf[4] << 4) | (buf[5] >> 4); - ovl->width = (((buf[2] & 0x0f) << 8) | buf[3]) - ovl->x + 1; - ovl->height = (((buf[5] & 0x0f) << 8) | buf[6]) - ovl->y + 1; - ovl->hili_top = -1; - ovl->hili_bottom = -1; - ovl->hili_left = -1; - ovl->hili_right = -1; - -#ifdef LOG_DEBUG - printf ("spu: \tx = %d y = %d width = %d height = %d\n", - ovl->x, ovl->y, ovl->width, ovl->height ); -#endif - state->modified = 1; - buf += 7; - break; - - case CMD_SPU_SET_PXD_OFFSET: /* image top[0] field / image bottom[1] field*/ - state->field_offs[0] = (((u_int)buf[1]) << 8) | buf[2]; - state->field_offs[1] = (((u_int)buf[3]) << 8) | buf[4]; - -#ifdef LOG_DEBUG - printf ("spu: \toffset[0] = %d offset[1] = %d\n", - state->field_offs[0], state->field_offs[1]); -#endif - - if ((state->field_offs[0] >= seq->seq_len) || - (state->field_offs[1] >= seq->seq_len)) { - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); - seq->broken = 1; - } - state->modified = 1; - buf += 5; - break; - - case CMD_SPU_WIPE: -#ifdef LOG_DEBUG - printf ("libspudec: \tSPU_WIPE not implemented yet\n"); -#endif - param_length = (buf[1] << 8) | (buf[2]); - buf += 1 + param_length; - break; - - case CMD_SPU_FORCE_DISPLAY: -#ifdef LOG_DEBUG - printf ("libspudec: \tForce Display/Menu\n"); -#endif - state->forced_display = 1; - buf++; - break; - - default: - xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec: unknown seqence command (%02x)\n", buf[0]); - /* FIXME: SPU should be dropped, and buffers resynced */ - buf = next_seq; - seq->broken = 1; - break; - } - } - - if (next_seq >= seq->buf + seq->seq_len) - seq->finished = 1; /* last sub-sequence */ -} - -/* FIXME: Get rid of all these static values */ -static uint8_t *bit_ptr[2]; -static int field; // which field we are currently decoding -static int put_x, put_y; - -static u_int get_bits (u_int bits) -{ - static u_int data; - static u_int bits_left; - u_int ret = 0; - - if (!bits) { /* for realignment to next byte */ - bits_left = 0; - } - - while (bits) { - if (bits > bits_left) { - ret |= data << (bits - bits_left); - bits -= bits_left; - - data = *bit_ptr[field]++; - bits_left = 8; - } else { - bits_left -= bits; - ret |= data >> (bits_left); - data &= (1 << bits_left) - 1; - bits = 0; - } - } - - return ret; -} - -static int spudec_next_line (vo_overlay_t *spu) -{ - get_bits (0); // byte align rle data - - put_x = 0; - put_y++; - field ^= 1; // Toggle fields - - if (put_y >= spu->height) { -#ifdef LOG_DEBUG - printf ("spu: put_y >= spu->height\n"); -#endif - return -1; - } - return 0; -} - -static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) -{ - rle_elem_t *rle; - field = 0; - bit_ptr[0] = seq->buf + state->field_offs[0]; - bit_ptr[1] = seq->buf + state->field_offs[1]; - put_x = put_y = 0; - get_bits (0); /* Reset/init bit code */ - -/* ovl->x = state->o_left; - * ovl->y = state->o_top; - * ovl->width = state->o_right - state->o_left + 1; - * ovl->height = state->o_bottom - state->o_top + 1; - - * ovl->hili_top = 0; - * ovl->hili_bottom = ovl->height - 1; - * ovl->hili_left = 0; - * ovl->hili_right = ovl->width - 1; - */ - - /* allocate for the worst case: - * - both fields running to the very end - * - 2 RLE elements per byte meaning single pixel RLE - */ - ovl->data_size = ((seq->cmd_offs - state->field_offs[0]) + - (seq->cmd_offs - state->field_offs[1])) * 2 * sizeof(rle_elem_t); - - if (ovl->rle) { - xprintf (xine, XINE_VERBOSITY_DEBUG, - "libspudec: spudec_draw_picture: ovl->rle is not empty!!!! It should be!!! " - "You should never see this message.\n"); - free(ovl->rle); - ovl->rle=NULL; - } - ovl->rle = malloc(ovl->data_size); - - state->modified = 0; /* mark as already processed */ - rle = ovl->rle; -#ifdef LOG_DEBUG - printf ("libspudec: Draw RLE=%p\n",rle); -#endif - - while (bit_ptr[1] < seq->buf + seq->cmd_offs) { - u_int len; - u_int vlc; - - vlc = get_bits (4); - if (vlc < 0x0004) { - vlc = (vlc << 4) | get_bits (4); - if (vlc < 0x0010) { - vlc = (vlc << 4) | get_bits (4); - if (vlc < 0x0040) { - vlc = (vlc << 4) | get_bits (4); - } - } - } - - len = vlc >> 2; - - /* if len == 0 -> end sequence - fill to end of line */ - if (len == 0) - len = ovl->width - put_x; - - rle->len = len; - rle->color = vlc & 0x03; - rle++; - put_x += len; - - if (put_x >= ovl->width) { - if (spudec_next_line (ovl) < 0) - break; - } - } - - ovl->num_rle = rle - ovl->rle; - ovl->rgb_clut = 0; - ovl->unscaled = 0; -#ifdef LOG_DEBUG - printf ("spu: Num RLE=%d\n",ovl->num_rle); - printf ("spu: Date size=%d\n",ovl->data_size); - printf ("spu: sizeof RLE=%d\n",sizeof(rle_elem_t)); -#endif -} - -/* Heuristic to discover the colors used by the subtitles - and assign a "readable" pallete to them. - Currently looks for sequence of border-fg-border or - border1-border2-fg-border2-border1. - MINFOUND is the number of ocurrences threshold. -*/ -#define MINFOUND 20 -static void spudec_discover_clut(xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl) -{ - int bg,c; - int seqcolor[10]; - int n,i; - rle_elem_t *rle; - - int found[2][16]; - - static clut_t text_clut[] = { - CLUT_Y_CR_CB_INIT(0x80, 0x90, 0x80), - CLUT_Y_CR_CB_INIT(0x00, 0x90, 0x00), - CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00) - }; - - memset(found,0,sizeof(found)); - rle = ovl->rle; - - /* this seems to be a problem somewhere else, - why rle is null? */ - if( !rle ) - return; - - /* suppose the first and last pixels are bg */ - if( rle[0].color != rle[ovl->num_rle-1].color ) - return; - - bg = rle[0].color; - - i = 0; - for( n = 0; n < ovl->num_rle; n++ ) - { - c = rle[n].color; - - if( c == bg ) - { - if( i == 3 && seqcolor[1] == seqcolor[3] ) - { - found[0][seqcolor[2]]++; - if( found[0][seqcolor[2]] > MINFOUND ) - { - memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[1], - sizeof(clut_t)); - memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[2], - sizeof(clut_t)); - ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; - ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; - state->need_clut = 0; - break; - } - } - if( i == 5 && seqcolor[1] == seqcolor[5] - && seqcolor[2] == seqcolor[4] ) - { - found[1][seqcolor[3]]++; - if( found[1][seqcolor[3]] > MINFOUND ) - { - memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[0], - sizeof(clut_t)); - memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[1], - sizeof(clut_t)); - memcpy(&state->clut[state->cur_colors[seqcolor[3]]], &text_clut[2], - sizeof(clut_t)); - ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; - ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; - ovl->color[seqcolor[3]] = state->clut[state->cur_colors[seqcolor[3]]]; - state->need_clut = 0; - break; - } - } - i = 0; - seqcolor[i] = c; - } - else if ( i < 6 ) - { - i++; - seqcolor[i] = c; - } - } -} - -#ifdef LOG_DEBUG -static void spudec_print_overlay( vo_overlay_t *ovl ) { - printf ("spu: OVERLAY to show\n"); - printf ("spu: \tx = %d y = %d width = %d height = %d\n", - ovl->x, ovl->y, ovl->width, ovl->height ); - printf ("spu: \tclut [%x %x %x %x]\n", - ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); - printf ("spu: \ttrans [%d %d %d %d]\n", - ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); - printf ("spu: \tclip top=%d bottom=%d left=%d right=%d\n", - ovl->hili_top, ovl->hili_bottom, ovl->hili_left, ovl->hili_right); - printf ("spu: \tclip_clut [%x %x %x %x]\n", - ovl->hili_color[0], ovl->hili_color[1], ovl->hili_color[2], ovl->hili_color[3]); - printf ("spu: \thili_trans [%d %d %d %d]\n", - ovl->hili_trans[0], ovl->hili_trans[1], ovl->hili_trans[2], ovl->hili_trans[3]); - return; -} -#endif - -int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, - int32_t button, int32_t mode, vo_overlay_t * overlay, vo_overlay_t * base ) { - btni_t *button_ptr = NULL; - unsigned int btns_per_group; - int i; - - if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) - return 0; - - btns_per_group = 36 / nav_pci->hli.hl_gi.btngr_ns; - - /* choose button group: we can always use a normal 4:3 or widescreen button group - * as long as xine blends the overlay before scaling the image to its aspect */ - if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 1 && !(nav_pci->hli.hl_gi.btngr1_dsp_ty & 6)) - button_ptr = &nav_pci->hli.btnit[0 * btns_per_group + button - 1]; - if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 2 && !(nav_pci->hli.hl_gi.btngr2_dsp_ty & 6)) - button_ptr = &nav_pci->hli.btnit[1 * btns_per_group + button - 1]; - if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 3 && !(nav_pci->hli.hl_gi.btngr3_dsp_ty & 6)) - button_ptr = &nav_pci->hli.btnit[2 * btns_per_group + button - 1]; - if (!button_ptr) { - xprintf(xine, XINE_VERBOSITY_DEBUG, - "libspudec: No suitable menu button group found, using group 1.\n"); - button_ptr = &nav_pci->hli.btnit[button - 1]; - } - - /* button areas in the nav packet are in screen coordinates, - * overlay clipping areas are in overlay coordinates; - * therefore we must subtract the display coordinates of the underlying overlay */ - overlay->hili_left = (button_ptr->x_start > base->x) ? (button_ptr->x_start - base->x) : 0; - overlay->hili_top = (button_ptr->y_start > base->y) ? (button_ptr->y_start - base->y) : 0; - overlay->hili_right = (button_ptr->x_end > base->x) ? (button_ptr->x_end - base->x) : 0; - overlay->hili_bottom = (button_ptr->y_end > base->y) ? (button_ptr->y_end - base->y) : 0; - if(button_ptr->btn_coln != 0) { -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: normal button clut\n"); -#endif - for (i = 0;i < 4; i++) { - overlay->hili_color[i] = clut[0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (16 + 4*i))]; - overlay->hili_trans[i] = 0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (4*i)); - } - } else { -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: abnormal button clut\n"); -#endif - for (i = 0;i < 4; i++) { -#ifdef LOG_BUTTON - printf("libspudec:btn_coln = 0, hili_color = color\n"); -#endif - overlay->hili_color[i] = overlay->color[i]; - overlay->hili_trans[i] = overlay->trans[i]; - } - } - - /* spudec_print_overlay( overlay ); */ -#ifdef LOG_BUTTON - printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n"); -#endif - - return 1; -} diff --git a/src/libspudec/spudec.h b/src/libspudec/spudec.h deleted file mode 100644 index 1e7d80596..000000000 --- a/src/libspudec/spudec.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * This file was originally part of the OMS program. - */ - -#ifndef __SPU_H__ -#define __SPU_H__ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#ifdef HAVE_DVDNAV -# include -#else -# include "nav_types.h" -#endif - -#define NUM_SEQ_BUFFERS 50 -#define MAX_STREAMS 32 - -typedef struct spudec_clut_struct { -#ifdef WORDS_BIGENDIAN - uint8_t entry0 : 4; - uint8_t entry1 : 4; - uint8_t entry2 : 4; - uint8_t entry3 : 4; -#else - uint8_t entry1 : 4; - uint8_t entry0 : 4; - uint8_t entry3 : 4; - uint8_t entry2 : 4; -#endif -} spudec_clut_t; - -typedef struct { - uint8_t *buf; - uint32_t ra_offs; /* reassembly offset */ - uint32_t seq_len; - uint32_t buf_len; - uint32_t cmd_offs; - int64_t pts; /* Base PTS of this sequence */ - int32_t finished; /* Has this control sequence been finished? */ - uint32_t complete; /* Has this reassembly been finished? */ - uint32_t broken; /* this SPU is broken and should be dropped */ -} spudec_seq_t; - -typedef struct { - uint8_t *cmd_ptr; - - uint32_t field_offs[2]; - int32_t b_top, o_top; - int32_t b_bottom, o_bottom; - int32_t b_left, o_left; - int32_t b_right, o_right; - - int32_t modified; /* Was the sub-picture modified? */ - int32_t visible; /* Must the sub-picture be shown? */ - int32_t forced_display; /* This overlay is a menu */ - int32_t delay; /* Delay in 90Khz / 1000 */ - int32_t need_clut; /* doesn't have the right clut yet */ - int32_t cur_colors[4];/* current 4 colors been used */ - int32_t vobsub; /* vobsub must be aligned to bottom */ - - uint32_t clut[16]; -} spudec_state_t; - -typedef struct spudec_stream_state_s { - spudec_seq_t ra_seq; - spudec_state_t state; - int64_t vpts; - int64_t pts; - int32_t overlay_handle; -} spudec_stream_state_t; - -typedef struct { - spu_decoder_class_t decoder_class; -} spudec_class_t; - -typedef struct pci_node_s pci_node_t; -struct pci_node_s { - pci_t pci; - uint64_t vpts; - pci_node_t *next; -}; - -typedef struct spudec_decoder_s { - spu_decoder_t spu_decoder; - - spudec_class_t *class; - xine_stream_t *stream; - spudec_stream_state_t spudec_stream_state[MAX_STREAMS]; - - video_overlay_event_t event; - video_overlay_object_t object; - int32_t menu_handle; - - spudec_state_t state; - - vo_overlay_t overlay; - int ovl_caps; - int output_open; - pthread_mutex_t nav_pci_lock; - pci_node_t pci_cur; - uint32_t buttonN; /* Current button number for highlights */ - int32_t button_filter; /* Allow highlight changes or not */ - int64_t last_event_vpts; -} spudec_decoder_t; - -void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len); -void spudec_process( spudec_decoder_t *this, int stream_id); -/* the nav functions must be called with the nav_pci_lock held */ -void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf); -void spudec_clear_nav_list(spudec_decoder_t *this); -void spudec_update_nav(spudec_decoder_t *this); -void spudec_process_nav(spudec_decoder_t *this); -int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, int32_t button, int32_t mode, - vo_overlay_t * overlay, vo_overlay_t * base ); - -#endif diff --git a/src/libspudec/xine_spu_decoder.c b/src/libspudec/xine_spu_decoder.c deleted file mode 100644 index e36b39fc8..000000000 --- a/src/libspudec/xine_spu_decoder.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * stuff needed to turn libspu into a xine decoder plugin - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include "xine-engine/bswap.h" -#include -#ifdef HAVE_DVDNAV -# include -# include -#else -# include "nav_read.h" -# include "nav_types.h" -#endif - -#include "spudec.h" - -/* -#define LOG_DEBUG 1 -#define LOG_BUTTON 1 -*/ - -static const clut_t default_clut[] = { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), - CLUT_Y_CR_CB_INIT(0x51, 0xef, 0x5a), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x36, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x51, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), - CLUT_Y_CR_CB_INIT(0x5c, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x1c, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef) -}; - -static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { - uint32_t stream_id; - spudec_seq_t *cur_seq; - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - stream_id = buf->type & 0x1f ; - cur_seq = &this->spudec_stream_state[stream_id].ra_seq; - -#ifdef LOG_DEBUG - printf("libspudec:got buffer type = %x\n", buf->type); -#endif - - /* check, if we need to process the next PCI from the list */ - pthread_mutex_lock(&this->nav_pci_lock); - spudec_update_nav(this); - pthread_mutex_unlock(&this->nav_pci_lock); - - if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || - !(buf->decoder_flags & BUF_FLAG_SPECIAL) || - buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) - return; - - if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_CLUT ) { -#ifdef LOG_DEBUG - printf("libspudec: SPU CLUT\n"); -#endif - if (buf->content[0]) { /* cheap endianess detection */ - xine_fast_memcpy(this->state.clut, buf->content, sizeof(uint32_t)*16); - } else { - int i; - uint32_t *clut = (uint32_t*) buf->content; - for (i = 0; i < 16; i++) - this->state.clut[i] = bswap_32(clut[i]); - } - this->state.need_clut = 0; - return; - } - - if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV ) { -#ifdef LOG_DEBUG - printf("libspudec:got nav packet 1\n"); -#endif - spudec_decode_nav(this,buf); - return; - } - - if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_VOBSUB_PACKAGE ) { - this->state.vobsub = 1; - } - -#ifdef LOG_DEBUG - printf("libspudec:got buffer type = %x\n", buf->type); -#endif - if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */ - return; - - if (buf->pts) { - metronom_t *metronom = this->stream->metronom; - int64_t vpts = metronom->got_spu_packet(metronom, buf->pts); - - this->spudec_stream_state[stream_id].vpts = vpts; /* Show timer */ - this->spudec_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */ - } - - spudec_reassembly(this->stream->xine, - &this->spudec_stream_state[stream_id].ra_seq, buf->content, buf->size); - if(this->spudec_stream_state[stream_id].ra_seq.complete == 1) { - if(this->spudec_stream_state[stream_id].ra_seq.broken) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); - this->spudec_stream_state[stream_id].ra_seq.broken = 0; - } else - spudec_process(this,stream_id); - } -} - -static void spudec_reset (spu_decoder_t *this_gen) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - int i; - - if( this->menu_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->menu_handle); - this->menu_handle = -1; - - for (i=0; i < MAX_STREAMS; i++) { - if( this->spudec_stream_state[i].overlay_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->spudec_stream_state[i].overlay_handle); - this->spudec_stream_state[i].overlay_handle = -1; - this->spudec_stream_state[i].ra_seq.complete = 1; - this->spudec_stream_state[i].ra_seq.broken = 0; - } - - pthread_mutex_lock(&this->nav_pci_lock); - spudec_clear_nav_list(this); - pthread_mutex_unlock(&this->nav_pci_lock); -} - -static void spudec_discontinuity (spu_decoder_t *this_gen) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - - pthread_mutex_lock(&this->nav_pci_lock); - spudec_clear_nav_list(this); - pthread_mutex_unlock(&this->nav_pci_lock); -} - - -static void spudec_dispose (spu_decoder_t *this_gen) { - - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - int i; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - - if( this->menu_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->menu_handle); - this->menu_handle = -1; - - for (i=0; i < MAX_STREAMS; i++) { - if( this->spudec_stream_state[i].overlay_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->spudec_stream_state[i].overlay_handle); - this->spudec_stream_state[i].overlay_handle = -1; - free (this->spudec_stream_state[i].ra_seq.buf); - } - - spudec_clear_nav_list(this); - pthread_mutex_destroy(&this->nav_pci_lock); - - free (this->event.object.overlay); - free (this); -} - -/* gets the current already correctly processed nav_pci info */ -/* This is not perfectly in sync with the display, but all the same, */ -/* much closer than doing it at the input stage. */ -/* returns a bool for error/success.*/ -static int spudec_get_interact_info (spu_decoder_t *this_gen, void *data) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - /*printf("get_interact_info() called\n");*/ - if (!this || !data) - return 0; - - /*printf("get_interact_info() coping nav_pci\n");*/ - pthread_mutex_lock(&this->nav_pci_lock); - spudec_update_nav(this); - memcpy(data, &this->pci_cur.pci, sizeof(pci_t) ); - pthread_mutex_unlock(&this->nav_pci_lock); - return 1; - -} - -static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t show) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - /* This function will move to video_overlay - * when video_overlay does menus */ - - video_overlay_manager_t *ovl_manager; - video_overlay_event_t *overlay_event = NULL; - vo_overlay_t *overlay = NULL; - overlay_event = xine_xmalloc (sizeof(video_overlay_event_t)); - - overlay = xine_xmalloc (sizeof(vo_overlay_t)); - /* FIXME: Watch out for threads. We should really put a lock on this - * because events is a different thread than decode_data */ - - if( this->menu_handle < 0 ) { - if (this->stream->video_out) { - ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - this->menu_handle = ovl_manager->get_handle(ovl_manager,1); - } - } -#ifdef LOG_BUTTON - printf ("libspudec:xine_decoder.c:spudec_event_listener:this=%p\n",this); - printf ("libspudec:xine_decoder.c:spudec_event_listener:this->menu_handle=%d\n",this->menu_handle); -#endif - if(this->menu_handle < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "Menu handle alloc failed. No more overlays objects available. Only %d at once please.", - MAX_OBJECTS); - free(overlay_event); - free(overlay); - return; - } - - if (show > 0) { -#ifdef LOG_NAV - fprintf (stderr,"libspudec:xine_decoder.c:spudec_event_listener:buttonN = %u show=%d\n", - button, - show); -#endif - this->buttonN = button; - if (this->button_filter != 1) { -#ifdef LOG_BUTTON - fprintf (stdout,"libspudec:xine_decoder.c:spudec_event_listener:buttonN updates not allowed\n"); -#endif - /* Only update highlight is the menu will let us */ - free(overlay_event); - free(overlay); - return; - } - if (show == 2) { - this->button_filter = 2; - } - pthread_mutex_lock(&this->nav_pci_lock); - spudec_update_nav(this); - overlay_event->object.handle = this->menu_handle; - overlay_event->object.pts = this->pci_cur.pci.hli.hl_gi.hli_s_ptm; - overlay_event->object.overlay=overlay; - overlay_event->event_type = OVERLAY_EVENT_MENU_BUTTON; -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec:Button Overlay\n"); -#endif - spudec_copy_nav_to_overlay(this->stream->xine, &this->pci_cur.pci, this->state.clut, - this->buttonN, show-1, overlay, &this->overlay ); - pthread_mutex_unlock(&this->nav_pci_lock); - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec:xine_decoder.c:spudec_event_listener:HIDE ????\n"); - printf("We dropped out here for some reason"); - _x_abort(); - overlay_event->object.handle = this->menu_handle; - overlay_event->event_type = OVERLAY_EVENT_HIDE; - } - overlay_event->vpts = 0; - if (this->stream->video_out) { - ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", - overlay_event->event_type, - this->stream->xine->clock->get_current_time(this->stream->xine->clock), - overlay_event->vpts); -#endif - ovl_manager->add_event (ovl_manager, (void *)overlay_event); - free(overlay_event); - free(overlay); - } else { - free(overlay_event); - free(overlay); - } - return; -} - -static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { - - spudec_decoder_t *this ; - int i; - - this = (spudec_decoder_t *) xine_xmalloc (sizeof (spudec_decoder_t)); - - this->spu_decoder.decode_data = spudec_decode_data; - this->spu_decoder.reset = spudec_reset; - this->spu_decoder.discontinuity = spudec_discontinuity; - this->spu_decoder.dispose = spudec_dispose; - this->spu_decoder.get_interact_info = spudec_get_interact_info; - this->spu_decoder.set_button = spudec_set_button; - this->stream = stream; - this->class = (spudec_class_t *) class_gen; - - this->menu_handle = -1; - this->buttonN = 1; - this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t)); - - pthread_mutex_init(&this->nav_pci_lock, NULL); - this->pci_cur.pci.hli.hl_gi.hli_ss = 0; - this->pci_cur.next = NULL; - - this->ovl_caps = stream->video_out->get_capabilities(stream->video_out); - this->output_open = 0; - this->last_event_vpts = 0; - for (i=0; i < MAX_STREAMS; i++) { - this->spudec_stream_state[i].ra_seq.complete = 1; - this->spudec_stream_state[i].overlay_handle = -1; - } - -/* FIXME:Do we really need a default clut? */ - xine_fast_memcpy(this->state.clut, default_clut, sizeof(this->state.clut)); - this->state.need_clut = 1; - this->state.vobsub = 0; - - return &this->spu_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - spudec_class_t *this; - - this = (spudec_class_t *) xine_xmalloc (sizeof (spudec_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "spudec"; - this->decoder_class.description = N_("DVD/VOB SPU decoder plugin"); - this->decoder_class.dispose = default_spu_decoder_class_dispose; - - lprintf ("libspudec:init_plugin called\n"); - return this; -} - -/* plugin catalog information */ -static uint32_t supported_types[] = { BUF_SPU_DVD, 0 }; - -static const decoder_info_t dec_info_data = { - supported_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_SPU_DECODER, 17, "spudec", XINE_VERSION_CODE, &dec_info_data, &init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libspudvb/Makefile.am b/src/libspudvb/Makefile.am deleted file mode 100644 index 1adb154db..000000000 --- a/src/libspudvb/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -xineplug_LTLIBRARIES = xineplug_decode_spudvb.la - -xineplug_decode_spudvb_la_SOURCES = xine_spudvb_decoder.c -xineplug_decode_spudvb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) diff --git a/src/libspudvb/xine_spudvb_decoder.c b/src/libspudvb/xine_spudvb_decoder.c deleted file mode 100644 index 9008260f7..000000000 --- a/src/libspudvb/xine_spudvb_decoder.c +++ /dev/null @@ -1,999 +0,0 @@ -/* - * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * DVB Subtitle decoder (ETS 300 743) - * (c) 2004 Mike Lampard - * based on the application dvbsub by Dave Chapman - * - * TODO: - * - Implement support for teletext based subtitles - */ - -#include "pthread.h" -#include -#include -#include -#include -#define MAX_REGIONS 7 - -/*#define LOG 1*/ - -typedef struct { - int x, y; - unsigned char is_visible; -} visible_region_t; - -typedef struct { - int page_time_out; - int page_version_number; - int page_state; - int page_id; - visible_region_t regions[MAX_REGIONS]; -} page_t; - -typedef struct { - int width, height; - int empty; - int depth; - int CLUT_id; - int objects_start; - int objects_end; - unsigned int object_pos[65536]; - unsigned char *img; - osd_object_t *osd; -} region_t; - -typedef struct { -/* dvbsub stuff */ - int x; - int y; - unsigned int curr_obj; - unsigned int curr_reg[64]; - uint8_t *buf; - int i; - int nibble_flag; - int in_scanline; - page_t page; - region_t regions[MAX_REGIONS]; - clut_t colours[MAX_REGIONS*256]; - unsigned char trans[MAX_REGIONS*256]; -} dvbsub_func_t; - -typedef struct dvb_spu_class_s { - spu_decoder_class_t class; - xine_t *xine; -} dvb_spu_class_t; - -typedef struct dvb_spu_decoder_s { - spu_decoder_t spu_decoder; - - dvb_spu_class_t *class; - xine_stream_t *stream; - - spu_dvb_descriptor_t *spu_descriptor; - - /* dvbsub_osd_mutex should be locked around all calls to this->osd_renderer->show() - and this->osd_renderer->hide() */ - pthread_mutex_t dvbsub_osd_mutex; - - char *pes_pkt; - char *pes_pkt_wrptr; - unsigned int pes_pkt_size; - - uint64_t pts; - uint64_t vpts; - uint64_t end_vpts; - - pthread_t dvbsub_timer_thread; - struct timespec dvbsub_hide_timeout; - pthread_cond_t dvbsub_restart_timeout; - dvbsub_func_t *dvbsub; - int show; -} dvb_spu_decoder_t; - - -static void update_osd(dvb_spu_decoder_t *this, int region_id) -{ - dvbsub_func_t *dvbsub = this->dvbsub; - region_t *reg = &dvbsub->regions[region_id]; - - if ( !reg->img ) { - if ( reg->osd ) { - pthread_mutex_lock( &this->dvbsub_osd_mutex ); - this->stream->osd_renderer->free_object( reg->osd ); - reg->osd = NULL; - pthread_mutex_unlock( &this->dvbsub_osd_mutex ); - } - return; - } - - if ( reg->osd ) { - if ( reg->width!=reg->osd->width || reg->height!=reg->osd->height ) { - pthread_mutex_lock( &this->dvbsub_osd_mutex ); - this->stream->osd_renderer->free_object( reg->osd ); - reg->osd = NULL; - pthread_mutex_unlock( &this->dvbsub_osd_mutex ); - } - } - - if ( !reg->osd ) - reg->osd = this->stream->osd_renderer->new_object( this->stream->osd_renderer, reg->width, reg->height ); -} - -static void update_region (dvb_spu_decoder_t * this, int region_id, int region_width, int region_height, int fill, int fill_color) -{ - - dvbsub_func_t *dvbsub = this->dvbsub; - region_t *reg = &dvbsub->regions[region_id]; - page_t *page = &dvbsub->page; - - /* reject invalid sizes and set some limits ! */ - if ( region_width<=0 || region_height<=0 || region_width>720 || region_height>576 ) { - if ( reg->img ) { - free( reg->img ); - reg->img = NULL; - } -#ifdef LOG - printf("SPUDVB: rejected region %d = %dx%d\n", region_id, region_width, region_height ); -#endif - return; - } - - if ( reg->width*reg->heightimg ) { - free( reg->img ); - reg->img = NULL; - } - } - - if ( !reg->img ) { - if ( !(reg->img=xine_xmalloc(region_width*region_height)) ) { - lprintf( "can't allocate mem for region %d\n", region_id ); - return; - } - fill_color = 15; - fill = 1; - } - - if ( fill ) { - memset( reg->img, fill_color, region_width*region_height ); - reg->empty = 1; -#ifdef LOG - printf("SPUDVB : FILL REGION %d\n", region_id); -#endif - } - reg->width = region_width; - reg->height = region_height; - page->regions[region_id].is_visible = 1; -} - - -static void do_plot (dvb_spu_decoder_t * this, int r, int x, int y, unsigned char pixel) -{ - int i; - dvbsub_func_t *dvbsub = this->dvbsub; - - i = (y * dvbsub->regions[r].width) + x; - /* do some clipping */ - if ( i<(dvbsub->regions[r].width*dvbsub->regions[r].height) ) { - dvbsub->regions[r].img[i] = pixel; - dvbsub->regions[r].empty = 0; - } -} - -static void plot (dvb_spu_decoder_t * this, int r, int run_length, unsigned char pixel) -{ - - dvbsub_func_t *dvbsub = this->dvbsub; - - int x2 = dvbsub->x + run_length; - - while (dvbsub->x < x2) { - do_plot (this, r, dvbsub->x, dvbsub->y, pixel); - dvbsub->x++; - } -} - -static unsigned char next_nibble (dvb_spu_decoder_t * this) -{ - unsigned char x; - dvbsub_func_t *dvbsub = this->dvbsub; - - if (dvbsub->nibble_flag == 0) { - x = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; - dvbsub->nibble_flag = 1; - } - else { - x = (dvbsub->buf[dvbsub->i++] & 0x0f); - dvbsub->nibble_flag = 0; - } - return (x); -} - -static void decode_4bit_pixel_code_string (dvb_spu_decoder_t * this, int r, int object_id, int ofs, int n) -{ - int next_bits, switch_1, switch_2, switch_3, run_length, pixel_code; - - dvbsub_func_t *dvbsub = this->dvbsub; - - int bits; - unsigned int data; - int j; - - if (dvbsub->in_scanline == 0) { - dvbsub->in_scanline = 1; - } - dvbsub->nibble_flag = 0; - j = dvbsub->i + n; - while (dvbsub->i < j) { - - bits = 0; - pixel_code = 0; - next_bits = next_nibble (this); - - if (next_bits != 0) { - pixel_code = next_bits; - plot (this, r, 1, pixel_code); - bits += 4; - } - else { - bits += 4; - data = next_nibble (this); - switch_1 = (data & 0x08) >> 3; - bits++; - if (switch_1 == 0) { - run_length = (data & 0x07); - bits += 3; - if (run_length != 0) { - plot (this, r, run_length + 2, pixel_code); - } - else { - break; - } - } - else { - switch_2 = (data & 0x04) >> 2; - bits++; - if (switch_2 == 0) { - run_length = (data & 0x03); - bits += 2; - pixel_code = next_nibble (this); - bits += 4; - plot (this, r, run_length + 4, pixel_code); - } - else { - switch_3 = (data & 0x03); - bits += 2; - switch (switch_3) { - case 0: - plot (this, r, 1, pixel_code); - break; - case 1: - plot (this, r, 2, pixel_code); - break; - case 2: - run_length = next_nibble (this); - bits += 4; - pixel_code = next_nibble (this); - bits += 4; - plot (this, r, run_length + 9, pixel_code); - break; - case 3: - run_length = next_nibble (this); - run_length = (run_length << 4) | next_nibble (this); - bits += 8; - pixel_code = next_nibble (this); - bits += 4; - plot (this, r, run_length + 25, pixel_code); - } - } - } - } - - } - if (dvbsub->nibble_flag == 1) { - dvbsub->i++; - dvbsub->nibble_flag = 0; - } -} - -static void recalculate_trans (dvb_spu_decoder_t *this) -{ - dvbsub_func_t *const dvbsub = this->dvbsub; - xine_spu_opacity_t opacity; - int i; - - _x_spu_get_opacity (this->stream->xine, &opacity); - for (i = 0; i < MAX_REGIONS * 256; ++i) { - /* ETSI-300-743 says "full transparency if Y == 0". */ - if (dvbsub->colours[i].y == 0) - dvbsub->trans[i] = 0; - else { - int v = _x_spu_calculate_opacity (&dvbsub->colours[i], dvbsub->colours[i].foo, &opacity); - dvbsub->trans[i] = v * 14 / 255 + 1; - } - } - -} - -static void set_clut(dvb_spu_decoder_t *this,int CLUT_id,int CLUT_entry_id,int Y_value, int Cr_value, int Cb_value, int T_value) { - - dvbsub_func_t *dvbsub = this->dvbsub; - - if ((CLUT_id>=MAX_REGIONS) || (CLUT_entry_id>15)) { - return; - } - - dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].y=Y_value; - dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].cr=Cr_value; - dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].cb=Cb_value; - dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].foo = T_value; -} - -static void process_CLUT_definition_segment(dvb_spu_decoder_t *this) { - int page_id, - segment_length, - CLUT_id, - CLUT_version_number; - - int CLUT_entry_id, - CLUT_flag_8_bit, - CLUT_flag_4_bit, - CLUT_flag_2_bit, - full_range_flag, - Y_value, - Cr_value, - Cb_value, - T_value; - dvbsub_func_t *dvbsub = this->dvbsub; - - int j; - - page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - j=dvbsub->i+segment_length; - - CLUT_id=dvbsub->buf[dvbsub->i++]; - CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4; - dvbsub->i++; - - while (dvbsub->i < j) { - CLUT_entry_id=dvbsub->buf[dvbsub->i++]; - - CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7; - CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6; - CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5; - full_range_flag=dvbsub->buf[dvbsub->i]&1; - dvbsub->i++; - - if (full_range_flag==1) { - Y_value=dvbsub->buf[dvbsub->i++]; - Cr_value=dvbsub->buf[dvbsub->i++]; - Cb_value=dvbsub->buf[dvbsub->i++]; - T_value=dvbsub->buf[dvbsub->i++]; - } else { - Y_value = dvbsub->buf[dvbsub->i] & 0xfc; - Cr_value = (dvbsub->buf[dvbsub->i] << 6 | dvbsub->buf[dvbsub->i + 1] >> 2) & 0xf0; - Cb_value = (dvbsub->buf[dvbsub->i + 1] << 2) & 0xf0; - T_value = (dvbsub->buf[dvbsub->i + 1] & 3) * 0x55; /* expand only this one to full range! */ - dvbsub->i+=2; - } - set_clut(this, CLUT_id,CLUT_entry_id,Y_value,Cr_value,Cb_value,T_value); - } -} - -static void process_pixel_data_sub_block (dvb_spu_decoder_t * this, int r, int o, int ofs, int n) -{ - int data_type; - int j; - - dvbsub_func_t *dvbsub = this->dvbsub; - - j = dvbsub->i + n; - - dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16; - dvbsub->y = ((dvbsub->regions[r].object_pos[o]) & 0xffff) + ofs; - while (dvbsub->i < j) { - data_type = dvbsub->buf[dvbsub->i++]; - - switch (data_type) { - case 0: - dvbsub->i++; - case 0x11: - decode_4bit_pixel_code_string (this, r, o, ofs, n - 1); - break; - case 0xf0: - dvbsub->in_scanline = 0; - dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16; - dvbsub->y += 2; - break; - default: - lprintf ("unimplemented data_type %02x in pixel_data_sub_block\n", data_type); - } - } - - dvbsub->i = j; -} - -static void process_page_composition_segment (dvb_spu_decoder_t * this) -{ - int segment_length; - int region_id, region_x, region_y; - int j; - int r; - dvbsub_func_t *dvbsub = this->dvbsub; - - dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - - j = dvbsub->i + segment_length; - - dvbsub->page.page_time_out = dvbsub->buf[dvbsub->i++]; - - dvbsub->page.page_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; - dvbsub->page.page_state = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; - dvbsub->i++; - if (dvbsub->page.page_state==2) { - for (r=0; rpage.regions[r].is_visible = 0; - } - else if ( dvbsub->page.page_state!=0 && dvbsub->page.page_state!=1 ) { - return; - } - - while (dvbsub->i < j) { - region_id = dvbsub->buf[dvbsub->i++]; - dvbsub->i++; /* reserved */ - region_x = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - region_y = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - - dvbsub->page.regions[region_id].x = region_x; - dvbsub->page.regions[region_id].y = region_y; - } -} - - -static void process_region_composition_segment (dvb_spu_decoder_t * this) -{ - int segment_length, - region_id, - region_version_number, - region_fill_flag, region_width, region_height, region_level_of_compatibility, region_depth, CLUT_id, region_8_bit_pixel_code, region_4_bit_pixel_code, region_2_bit_pixel_code; - int object_id, object_type, object_provider_flag, object_x, object_y, foreground_pixel_code, background_pixel_code; - int j; - int o; - dvbsub_func_t *dvbsub = this->dvbsub; - - dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - j = dvbsub->i + segment_length; - - region_id = dvbsub->buf[dvbsub->i++]; - region_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; - region_fill_flag = (dvbsub->buf[dvbsub->i] & 0x08) >> 3; - dvbsub->i++; - region_width = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - region_height = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5; - region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2; - dvbsub->i++; - CLUT_id = dvbsub->buf[dvbsub->i++]; - region_8_bit_pixel_code = dvbsub->buf[dvbsub->i++]; - region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; - region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; - dvbsub->i++; - - if(region_id>=MAX_REGIONS) - return; - - /* Check if region size has changed and fill background. */ - update_region (this, region_id, region_width, region_height, region_fill_flag, region_4_bit_pixel_code); - if ( CLUT_idregions[region_id].CLUT_id = CLUT_id; - - dvbsub->regions[region_id].objects_start = dvbsub->i; - dvbsub->regions[region_id].objects_end = j; - - for (o = 0; o < 65536; o++) { - dvbsub->regions[region_id].object_pos[o] = 0xffffffff; - } - - while (dvbsub->i < j) { - object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6; - object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4; - object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - - dvbsub->regions[region_id].object_pos[object_id] = (object_x << 16) | object_y; - - if ((object_type == 0x01) || (object_type == 0x02)) { - foreground_pixel_code = dvbsub->buf[dvbsub->i++]; - background_pixel_code = dvbsub->buf[dvbsub->i++]; - } - } - -} - -static void process_object_data_segment (dvb_spu_decoder_t * this) -{ - int segment_length, object_id, object_version_number, object_coding_method, non_modifying_colour_flag; - - int top_field_data_block_length, bottom_field_data_block_length; - - dvbsub_func_t *dvbsub = this->dvbsub; - - int j; - int old_i; - int r; - - dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - j = dvbsub->i + segment_length; - - object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - dvbsub->curr_obj = object_id; - object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; - object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; - non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1; - dvbsub->i++; - - old_i = dvbsub->i; - for (r = 0; r < MAX_REGIONS; r++) { - - /* If this object is in this region... */ - if (dvbsub->regions[r].img) { - if (dvbsub->regions[r].object_pos[object_id] != 0xffffffff) { - dvbsub->i = old_i; - if (object_coding_method == 0) { - top_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - bottom_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; - dvbsub->i += 2; - - process_pixel_data_sub_block (this, r, object_id, 0, top_field_data_block_length); - - process_pixel_data_sub_block (this, r, object_id, 1, bottom_field_data_block_length); - } - } - } - } -} - -static void unlock_mutex_cancellation_func(void *mutex_gen) -{ - pthread_mutex_t *mutex = (pthread_mutex_t*) mutex_gen; - pthread_mutex_unlock(mutex); -} - -/* Thread routine that checks for subtitle timeout periodically. - To avoid unexpected subtitle hiding, calls to this->stream->osd_renderer->show() - should be in blocks like: - - pthread_mutex_lock(&this->dvbsub_osd_mutex); - this->stream->osd_renderer->show(...); - this->dvbsub_hide_timeout.tv_sec = time(NULL) + timeout value; - pthread_cond_signal(&this->dvbsub_restart_timeout); - pthread_mutex_unlock(&this->dvbsub_osd_mutex); - - This ensures that the timeout is changed with the lock held, and - that the thread is signalled to pick up the new timeout. -*/ -static void* dvbsub_timer_func(void *this_gen) -{ - dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - pthread_mutex_lock(&this->dvbsub_osd_mutex); - int i; - - /* If we're cancelled via pthread_cancel, unlock the mutex */ - pthread_cleanup_push(unlock_mutex_cancellation_func, &this->dvbsub_osd_mutex); - - while(1) - { - /* Record the current timeout, and wait - note that pthread_cond_timedwait - will unlock the mutex on entry, and lock it on exit */ - struct timespec timeout = this->dvbsub_hide_timeout; - int result = pthread_cond_timedwait(&this->dvbsub_restart_timeout, - &this->dvbsub_osd_mutex, - &this->dvbsub_hide_timeout); - if(result == ETIMEDOUT && - timeout.tv_sec == this->dvbsub_hide_timeout.tv_sec && - timeout.tv_nsec == this->dvbsub_hide_timeout.tv_nsec) - { - /* We timed out, and no-one changed the timeout underneath us. - Hide the OSD, then wait until we're signalled. */ - if(this && this->stream && this->stream->osd_renderer) - { - for ( i=0; idvbsub->regions[i].osd ) { - this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 ); -#ifdef LOG - printf("SPUDVB: thread hiding = %d\n",i); -#endif - } - } - } - pthread_cond_wait(&this->dvbsub_restart_timeout, &this->dvbsub_osd_mutex); - } - } - - pthread_cleanup_pop(1); - return NULL; -} - -static void downscale_region_image( region_t *reg, unsigned char *dest, int dest_width ) -{ - float i, k, inc=reg->width/(float)dest_width; - int j; - for ( j=0; jheight; j++ ) { - for ( i=0,k=0; iwidth && kimg[(j*reg->width)+(int)i]; - } - } -} - -static void draw_subtitles (dvb_spu_decoder_t * this) -{ - int r; - int display=0; - int64_t dum; - int dest_width=0, dest_height, reg_width; - this->stream->video_out->status(this->stream->video_out, NULL, &dest_width, &dest_height, &dum); - unsigned char tmp[dest_width*576]; - unsigned char *reg; - - if ( !dest_width ) - return; - - /* render all regions onto the page */ - - for ( r=0; rdvbsub->page.regions[r].is_visible ) - display++; - } - if ( !display ) - return; - - for (r = 0; r < MAX_REGIONS; r++) { - if (this->dvbsub->regions[r].img) { - if (this->dvbsub->page.regions[r].is_visible && !this->dvbsub->regions[r].empty) { - update_osd( this, r ); - if ( !this->dvbsub->regions[r].osd ) - continue; - /* clear osd */ - this->stream->osd_renderer->clear( this->dvbsub->regions[r].osd ); - if (this->dvbsub->regions[r].width>dest_width) { - downscale_region_image(&this->dvbsub->regions[r], tmp, dest_width); - reg = tmp; - reg_width = dest_width; - } - else { - reg = this->dvbsub->regions[r].img; - reg_width = this->dvbsub->regions[r].width; - } - this->stream->osd_renderer->set_palette( this->dvbsub->regions[r].osd, (uint32_t*)(&this->dvbsub->colours[this->dvbsub->regions[r].CLUT_id*256]), &this->dvbsub->trans[this->dvbsub->regions[r].CLUT_id*256]); - this->stream->osd_renderer->draw_bitmap( this->dvbsub->regions[r].osd, reg, 0, 0, reg_width, this->dvbsub->regions[r].height, NULL ); - } - } - } - - pthread_mutex_lock(&this->dvbsub_osd_mutex); -#ifdef LOG - printf("SPUDVB: this->vpts=%llu\n",this->vpts); -#endif - for ( r=0; rdvbsub->page.regions[r].is_visible && this->dvbsub->regions[r].osd && !this->dvbsub->regions[r].empty ) { - this->stream->osd_renderer->set_position( this->dvbsub->regions[r].osd, this->dvbsub->page.regions[r].x, this->dvbsub->page.regions[r].y ); - this->stream->osd_renderer->show( this->dvbsub->regions[r].osd, this->vpts ); -#ifdef LOG - printf("SPUDVB: show region = %d\n",r); -#endif - } - else { - if ( this->dvbsub->regions[r].osd ) { - this->stream->osd_renderer->hide( this->dvbsub->regions[r].osd, this->vpts ); -#ifdef LOG - printf("SPUDVB: hide region = %d\n",r); -#endif - } - } - } - this->dvbsub_hide_timeout.tv_nsec = 0; - this->dvbsub_hide_timeout.tv_sec = time(NULL) + this->dvbsub->page.page_time_out; -#ifdef LOG - printf("SPUDVB: page_time_out %d\n",this->dvbsub->page.page_time_out); -#endif - pthread_cond_signal(&this->dvbsub_restart_timeout); - pthread_mutex_unlock(&this->dvbsub_osd_mutex); -} - - -static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf) -{ - dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - int new_i; - int data_identifier, subtitle_stream_id; - int segment_length, segment_type; - int PES_header_data_length; - int PES_packet_length; - int i; - - if((buf->type & 0xffff0000)!=BUF_SPU_DVB) - return; - - if (buf->decoder_flags & BUF_FLAG_SPECIAL) { - if (buf->decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR) { - if (buf->decoder_info[2] == 0) { - /* Hide the osd - note that if the timeout thread times out, it'll rehide, which is harmless */ - pthread_mutex_lock(&this->dvbsub_osd_mutex); - for ( i=0; idvbsub->regions[i].osd ) - this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 ); - } - pthread_mutex_unlock(&this->dvbsub_osd_mutex); - } - else { - xine_fast_memcpy (this->spu_descriptor, buf->decoder_info_ptr[2], buf->decoder_info[2]); - } - } - return; - } - else { - if (buf->decoder_info[2]) { - memset (this->pes_pkt, 0xff, 64*1024); - this->pes_pkt_wrptr = this->pes_pkt; - this->pes_pkt_size = buf->decoder_info[2]; - this->pts = buf->pts; - - xine_fast_memcpy (this->pes_pkt, buf->content, buf->size); - this->pes_pkt_wrptr += buf->size; - } - else { - if (this->pes_pkt && (this->pes_pkt_wrptr != this->pes_pkt)) { - xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size); - this->pes_pkt_wrptr += buf->size; - } - } - } - /* don't ask metronom for a vpts but rather do the calculation - * because buf->pts could be too far in future and metronom won't accept - * further backwards pts (see metronom_got_spu_packet) */ - if (buf->pts) { - metronom_t *metronom = this->stream->metronom; - int64_t vpts_offset = metronom->get_option( metronom, METRONOM_VPTS_OFFSET ); - int64_t spu_offset = metronom->get_option( metronom, METRONOM_SPU_OFFSET ); - int64_t vpts = (int64_t)(buf->pts)+vpts_offset+spu_offset; - metronom_clock_t *clock = this->stream->xine->clock; - int64_t curvpts = clock->get_current_time( clock ); - /* if buf->pts is unreliable, show page asap (better than nothing) */ -#ifdef LOG - printf("SPUDVB: spu_vpts=%lld - current_vpts=%lld\n", vpts, curvpts); -#endif - if ( vpts<=curvpts || (vpts-curvpts)>(5*90000) ) - this->vpts = 0; - else - this->vpts = vpts; - } - - /* process the pes section */ - - PES_packet_length = this->pes_pkt_size; - - this->dvbsub->buf = this->pes_pkt; - - PES_header_data_length = 0; - this->dvbsub->i = 0; - - data_identifier = this->dvbsub->buf[this->dvbsub->i++]; - subtitle_stream_id = this->dvbsub->buf[this->dvbsub->i++]; - - while (this->dvbsub->i <= (PES_packet_length)) { - /* SUBTITLING SEGMENT */ - this->dvbsub->i++; - segment_type = this->dvbsub->buf[this->dvbsub->i++]; - - this->dvbsub->page.page_id = (this->dvbsub->buf[this->dvbsub->i] << 8) | this->dvbsub->buf[this->dvbsub->i + 1]; - segment_length = (this->dvbsub->buf[this->dvbsub->i + 2] << 8) | this->dvbsub->buf[this->dvbsub->i + 3]; - new_i = this->dvbsub->i + segment_length + 4; - - /* only process complete segments */ - if(new_i > (this->pes_pkt_wrptr - this->pes_pkt)) - break; - /* verify we've the right segment */ - if(this->dvbsub->page.page_id==this->spu_descriptor->comp_page_id){ - /* SEGMENT_DATA_FIELD */ - switch (segment_type & 0xff) { - case 0x10: - process_page_composition_segment (this); - break; - case 0x11: - process_region_composition_segment (this); - break; - case 0x12: - process_CLUT_definition_segment(this); - break; - case 0x13: - process_object_data_segment (this); - break; - case 0x80: /* Page is now completely rendered */ - recalculate_trans(this); - draw_subtitles( this ); - break; - default: - return; - break; - } - } - this->dvbsub->i = new_i; - } - - return; -} - -static void spudec_reset (spu_decoder_t * this_gen) -{ - dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - int i; - - /* Hide the osd - if the timeout thread times out, it'll rehide harmlessly */ - pthread_mutex_lock(&this->dvbsub_osd_mutex); - for ( i=0; idvbsub->regions[i].osd ) - this->stream->osd_renderer->hide(this->dvbsub->regions[i].osd, 0); - } - pthread_mutex_unlock(&this->dvbsub_osd_mutex); - -} - -static void spudec_discontinuity (spu_decoder_t * this_gen) -{ - /* do nothing */ -} - -static void spudec_dispose (spu_decoder_t * this_gen) -{ - dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - int i; - - pthread_cancel(this->dvbsub_timer_thread); - pthread_join(this->dvbsub_timer_thread, NULL); - pthread_mutex_destroy(&this->dvbsub_osd_mutex); - pthread_cond_destroy(&this->dvbsub_restart_timeout); - - if(this->spu_descriptor){ - free(this->spu_descriptor); - this->spu_descriptor=NULL; - } - - for ( i=0; idvbsub->regions[i].img ) - free( this->dvbsub->regions[i].img ); - if ( this->dvbsub->regions[i].osd ) - this->stream->osd_renderer->free_object( this->dvbsub->regions[i].osd ); - } - - if (this->pes_pkt) - free (this->pes_pkt); - - if (this->dvbsub) - free (this->dvbsub); - - free (this); -} - -static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream) -{ - - int i; - dvb_spu_decoder_t *this; - dvb_spu_class_t *class = (dvb_spu_class_t *) class_gen; - - this = (dvb_spu_decoder_t *) xine_xmalloc (sizeof (dvb_spu_decoder_t)); - - this->spu_decoder.decode_data = spudec_decode_data; - this->spu_decoder.reset = spudec_reset; - this->spu_decoder.discontinuity = spudec_discontinuity; - this->spu_decoder.dispose = spudec_dispose; - this->spu_decoder.get_interact_info = NULL; - this->spu_decoder.set_button = NULL; - - this->class = class; - this->stream = stream; - - this->pes_pkt = xine_xmalloc (1024*65); - this->spu_descriptor = xine_xmalloc(sizeof(spu_dvb_descriptor_t)); - - this->dvbsub = xine_xmalloc (sizeof (dvbsub_func_t)); - - for (i = 0; i < MAX_REGIONS; i++) { - this->dvbsub->page.regions[i].is_visible = 0; - this->dvbsub->regions[i].img = NULL; - this->dvbsub->regions[i].osd = NULL; - this->dvbsub->regions[i].CLUT_id = 0; - } - - { - xine_spu_opacity_t opacity; - static const clut_t black = { 0, 0, 0, 0 }; - int t; - - _x_spu_get_opacity (this->stream->xine, &opacity); - t = _x_spu_calculate_opacity (&black, 0, &opacity); - - for (i = 0; i < MAX_REGIONS * 256; i++) - this->dvbsub->colours[i].foo = t; - } - - pthread_mutex_init(&this->dvbsub_osd_mutex, NULL); - pthread_cond_init(&this->dvbsub_restart_timeout, NULL); - this->dvbsub_hide_timeout.tv_nsec = 0; - this->dvbsub_hide_timeout.tv_sec = time(NULL); - pthread_create(&this->dvbsub_timer_thread, NULL, dvbsub_timer_func, this); - - return (spu_decoder_t *) this; -} - -static void *init_spu_decoder_plugin (xine_t * xine, void *data) -{ - - dvb_spu_class_t *this; - this = (dvb_spu_class_t *) xine_xmalloc (sizeof (dvb_spu_class_t)); - - this->class.open_plugin = dvb_spu_class_open_plugin; - this->class.identifier = "spudvb"; - this->class.description = N_("DVB subtitle decoder plugin"); - this->class.dispose = default_spu_decoder_class_dispose; - - this->xine = xine; - - return &this->class; -} - - -/* plugin catalog information */ -static uint32_t supported_types[] = { BUF_SPU_DVB, 0 }; - -static const decoder_info_t spudec_info = { - supported_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { -/* type, API, "name", version, special_info, init_function */ - {PLUGIN_SPU_DECODER, 17, "spudvb", XINE_VERSION_CODE, &spudec_info, - &init_spu_decoder_plugin}, - {PLUGIN_NONE, 0, "", 0, NULL, NULL} -}; diff --git a/src/libsputext/Makefile.am b/src/libsputext/Makefile.am deleted file mode 100644 index 14c6f2323..000000000 --- a/src/libsputext/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -xineplug_LTLIBRARIES = xineplug_decode_sputext.la xineplug_dmx_sputext.la - -xineplug_dmx_sputext_la_SOURCES = demux_sputext.c -xineplug_dmx_sputext_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) - -xineplug_decode_sputext_la_SOURCES = xine_sputext_decoder.c -xineplug_decode_sputext_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c deleted file mode 100644 index 270894f50..000000000 --- a/src/libsputext/demux_sputext.c +++ /dev/null @@ -1,1489 +0,0 @@ -/* - * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * code based on old libsputext/xine_decoder.c - * - * code based on mplayer module: - * - * Subtitle reader with format autodetection - * - * Written by laaz - * Some code cleanup & realloc() by A'rpi/ESP-team - * dunnowhat sub format by szabi - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "demux_sputext" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include - -#define ERR (void *)-1 -#define SUB_MAX_TEXT 5 -#define SUB_BUFSIZE 1024 -#define LINE_LEN 1000 -#define LINE_LEN_QUOT "1000" - -/* - * Demuxer typedefs - */ - -typedef struct { - - int lines; - - long start; /* csecs */ - long end; /* csecs */ - - char *text[SUB_MAX_TEXT]; - -} subtitle_t; - - -typedef struct { - - demux_plugin_t demux_plugin; - xine_stream_t *stream; - input_plugin_t *input; - - int status; - - char buf[SUB_BUFSIZE]; - off_t buflen; - - float mpsub_position; - - int uses_time; - int errs; - subtitle_t *subtitles; - int num; /* number of subtitle structs */ - int cur; /* current subtitle */ - int format; /* constants see below */ - char next_line[SUB_BUFSIZE]; /* a buffer for next line read from file */ - -} demux_sputext_t; - -typedef struct demux_sputext_class_s { - - demux_class_t demux_class; - - int max_timeout; /* default timeout of hidding subtitles */ - -} demux_sputext_class_t; - -/* - * Demuxer code start - */ - -#define FORMAT_UNKNOWN -1 -#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_PJS 7 -#define FORMAT_MPSUB 8 -#define FORMAT_AQTITLE 9 -#define FORMAT_JACOBSUB 10 -#define FORMAT_SUBVIEWER2 11 -#define FORMAT_SUBRIP09 12 -#define FORMAT_MPL2 13 /*Mplayer sub 2 ?*/ - -static int eol(char p) { - return (p=='\r' || p=='\n' || p=='\0'); -} - -static inline void trail_space(char *s) { - int i; - while (isspace(*s)) { - char *copy = s; - do { - copy[0] = copy[1]; - copy++; - } while(*copy); - } - i = strlen(s) - 1; - while (i > 0 && isspace(s[i])) - s[i--] = '\0'; -} - -/* - * Reimplementation of fgets() using the input->read() method. - */ -static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len) { - off_t nread = 0; - char *s; - int linelen; - - if ((len - this->buflen) > 512) { - if((nread = this->input->read(this->input, - &this->buf[this->buflen], len - this->buflen)) < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "read failed.\n"); - return NULL; - } - } - - this->buflen += nread; - this->buf[this->buflen] = '\0'; - - s = strchr(this->buf, '\n'); - - if (line && (s || this->buflen)) { - - linelen = s ? (s - this->buf) + 1 : this->buflen; - - memcpy(line, this->buf, linelen); - line[linelen] = '\0'; - - memmove(this->buf, &this->buf[linelen], SUB_BUFSIZE - linelen); - this->buflen -= linelen; - - return line; - } - - return NULL; -} - - -static subtitle_t *sub_read_line_sami(demux_sputext_t *this, subtitle_t *current) { - - static char line[LINE_LEN + 1]; - static char *s = NULL; - char text[LINE_LEN + 1], *p, *q; - int state; - - p = NULL; - current->lines = current->start = 0; - current->end = -1; - state = 0; - - /* read the first line */ - if (!s) - if (!(s = read_line_from_input(this, line, LINE_LEN))) 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 "" */ - 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, "
", 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 */ - 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 = read_line_from_input (this, line, LINE_LEN))) - 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(demux_sputext_t *this, subtitle_t *current) { - - char line[LINE_LEN + 1]; - char line2[LINE_LEN + 1]; - char *p, *next; - int i; - - memset (current, 0, sizeof(subtitle_t)); - - current->end=-1; - do { - if (!read_line_from_input (this, line, LINE_LEN)) return NULL; - } while ((sscanf (line, "{%ld}{}%" LINE_LEN_QUOT "[^\r\n]", &(current->start), line2) !=2) && - (sscanf (line, "{%ld}{%ld}%" LINE_LEN_QUOT "[^\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) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); - current->lines=i; - return current; - } - } - current->lines= ++i; - - return current; -} - -static subtitle_t *sub_read_line_subviewer(demux_sputext_t *this, subtitle_t *current) { - - char line[LINE_LEN + 1]; - int a1,a2,a3,a4,b1,b2,b3,b4; - char *p=NULL, *q=NULL; - int len; - - memset (current, 0, sizeof(subtitle_t)); - - while (1) { - if (!read_line_from_input(this, line, LINE_LEN)) return NULL; - if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) { - 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 (!read_line_from_input(this, line, LINE_LEN)) - 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' && *p!='|' && strncasecmp(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; - if (*p=='[') while (*p++!=']'); - if (*p=='|') p++; - } - if (current->lines > SUB_MAX_TEXT) current->lines = SUB_MAX_TEXT; - break; - } - return current; -} - -static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *current) { - char line[LINE_LEN + 1]; - int a1,a2,a3,a4,b1,b2,b3,b4; - int i,end_sub; - - memset(current,0,sizeof(subtitle_t)); - do { - if(!read_line_from_input(this,line,LINE_LEN)) - return NULL; - i = sscanf(line,"%d:%d:%d%*[,.]%d --> %d:%d:%d%*[,.]%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4); - } while(i < 8); - current->start = a1*360000+a2*6000+a3*100+a4/10; - current->end = b1*360000+b2*6000+b3*100+b4/10; - i=0; - end_sub=0; - do { - char *p; /* pointer to the curently read char */ - char temp_line[SUB_BUFSIZE]; /* subtitle line that will be transfered to current->text[i] */ - int temp_index; /* ... and its index wich 'points' to the first EMPTY place -> last read char is at temp_index-1 if temp_index>0 */ - temp_line[SUB_BUFSIZE-1]='\0'; /* just in case... */ - if(!read_line_from_input(this,line,LINE_LEN)) { - if(i) - break; /* if something was read, transmit it */ - else - return NULL; /* if not, repport EOF */ - } - for(temp_index=0,p=line;*p!='\0' && !end_sub && temp_index0) { - if(temp_index==SUB_BUFSIZE) - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many characters in a subtitle line\n"); - if(temp_line[temp_index-1]=='\0' || temp_index==SUB_BUFSIZE) { - if(temp_index>1) { /* more than 1 char (including '\0') -> that is a valid one */ - current->text[i]=(char *)xine_xmalloc(temp_index); - if(!current->text[i]) - return ERR; - strncpy(current->text[i],temp_line,temp_index); /* temp_index<=SUB_BUFSIZE is always true here */ - i++; - temp_index=0; - } else - end_sub=1; - } - } - } - } while(i=SUB_MAX_TEXT) - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); - current->lines=i; - return current; -} - -static subtitle_t *sub_read_line_vplayer(demux_sputext_t *this,subtitle_t *current) { - char line[LINE_LEN + 1]; - int a1,a2,a3,b1,b2,b3; - char *p=NULL, *next, *p2; - int i; - - memset (current, 0, sizeof(subtitle_t)); - - while (!current->text[0]) { - if( this->next_line[0] == '\0' ) { /* if the buffer is empty.... */ - if( !read_line_from_input(this, line, LINE_LEN) ) return NULL; - } else { - /* ... get the current line from buffer. */ - strncpy( line, this->next_line, LINE_LEN); - line[LINE_LEN] = '\0'; /* I'm scared. This makes me feel better. */ - this->next_line[0] = '\0'; /* mark the buffer as empty. */ - } - /* Initialize buffer with next line */ - if( ! read_line_from_input( this, this->next_line, LINE_LEN) ) { - this->next_line[0] = '\0'; - return NULL; - } - if( (sscanf( line, "%d:%d:%d:", &a1, &a2, &a3) < 3) || - (sscanf( this->next_line, "%d:%d:%d:", &b1, &b2, &b3) < 3) ) - continue; - current->start = a1*360000+a2*6000+a3*100; - current->end = b1*360000+b2*6000+b3*100; - if ((current->end - current->start) > LINE_LEN) - current->end = current->start + LINE_LEN; /* not too long though. */ - /* teraz czas na wkopiowanie stringu */ - p=line; - /* finds the body of the subtitle_t */ - for (i=0; i<3; i++){ - p2=strchr( p, ':'); - if( p2 == NULL ) break; - p=p2+1; - } - - 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) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); - current->lines=i; - return current; - } - } - current->lines=++i; - } - return current; -} - -static subtitle_t *sub_read_line_rt(demux_sputext_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[LINE_LEN + 1]; - int a1,a2,a3,a4,b1,b2,b3,b4; - char *p=NULL,*next=NULL; - int i,len,plen; - - memset (current, 0, sizeof(subtitle_t)); - - while (!current->text[0]) { - if (!read_line_from_input(this, line, LINE_LEN)) 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, "
in it */ + xml_node_t *clip_node; + + /* iterate through each tag contained in the tag to look for */ + + for (clip_node = packet_xml_root->child; clip_node != NULL; clip_node = clip_node->next) { + + if (strcasecmp (clip_node->name, "a") == 0) { + xml_property_t *href_property; + + /* found the tag: grab its value and its href property */ + + if (clip_node->data) + anchor_text = strdup (clip_node->data); + + for (href_property = clip_node->props; href_property != NULL; href_property = href_property->next) { + if (strcasecmp (href_property->name, "href") == 0) { + /* found the href property */ + char *href = href_property->value; + + if (href) { + lprintf ("found href: \"%s\"\n", href); + this->current_anchor.href = strdup(href); + } + } + } + } + } + } + + /* finish here if we don't have to process any anchor text */ + if (!anchor_text) + return; + + /* how many lines does the anchor text take up? */ + this->lines=0; + { + int i = 0; + while (*anchor_text) { + if (*anchor_text == '\r' || *anchor_text == '\n') { + if (i) { + /* match a newline and there are chars on the current line ... */ + this->text[ this->lines ][i] = '\0'; + this->lines++; + i = 0; + } + } else { + /* found a normal (non-line-ending) character */ + this->text[ this->lines ][i] = *anchor_text; + if (itext[ this->lines ][i] = '\0'; + this->lines++; + } + } + + /* initialize decoder if needed */ + if( !this->cached_width || !this->cached_height || !this->cached_img_duration || !this->osd ) { + if( this->stream->video_out->status(this->stream->video_out, NULL, + &this->cached_width, &this->cached_height, &this->cached_img_duration )) { + if( this->cached_width && this->cached_height && this->cached_img_duration ) { + lprintf("this->stream->osd_renderer is %p\n", this->stream->osd_renderer); + } + } + } + + update_font_size (this); + + if( this->osd ) { + draw_subtitle(this, buf->pts); + return; + } else { + lprintf ("libspucmml: no osd\n"); + } + + return; +} + +static void video_frame_format_change_callback (void *user_data, const xine_event_t *event) +{ + /* this doesn't do anything for now: it's a start at attempting to display + * CMML clips which occur at 0 seconds into the track. see + * + * http://marc.theaimsgroup.com/?l=xine-devel&m=109202443013890&w=2 + * + * for a description of the problem. */ + + switch (event->type) { + case XINE_EVENT_FRAME_FORMAT_CHANGE: + lprintf("video_frame_format_change_callback called!\n"); + break; + default: + lprintf("video_frame_format_change_callback called with unknown event %d\n", event->type); + break; + } +} + +static void spudec_reset (spu_decoder_t *this_gen) { + spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; + + this->cached_width = this->cached_height = 0; +} + +static void spudec_discontinuity (spu_decoder_t *this_gen) { + /* do nothing */ +} + +static void spudec_dispose (spu_decoder_t *this_gen) { + spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; + + if (this->event_queue) + xine_event_dispose_queue (this->event_queue); + + if (this->osd) { + this->stream->osd_renderer->free_object (this->osd); + this->osd = NULL; + } + free(this); +} + +static void update_vertical_offset(void *this_gen, xine_cfg_entry_t *entry) +{ + spucmml_decoder_t *this = (spucmml_decoder_t *)this_gen; + + this->vertical_offset = entry->num_value; + update_font_size(this); +} + +static void update_osd_font(void *this_gen, xine_cfg_entry_t *entry) +{ + spucmml_decoder_t *this = (spucmml_decoder_t *)this_gen; + + this->font = entry->str_value; + + if( this->stream->osd_renderer ) + this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); +} + +static spu_decoder_t *spucmml_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { + + spucmml_class_t *class = (spucmml_class_t *)class_gen; + spucmml_decoder_t *this ; + + this = (spucmml_decoder_t *) xine_xmalloc (sizeof (spucmml_decoder_t)); + + this->spu_decoder.decode_data = spudec_decode_data; + this->spu_decoder.reset = spudec_reset; + this->spu_decoder.discontinuity = spudec_discontinuity; + this->spu_decoder.dispose = spudec_dispose; + this->spu_decoder.get_interact_info = NULL; + this->spu_decoder.set_button = NULL; + this->spu_decoder.dispose = spudec_dispose; + + this->class = class; + this->stream = stream; + + this->event_queue = xine_event_new_queue (this->stream); + xine_event_create_listener_thread (this->event_queue, + video_frame_format_change_callback, + this); + + this->font_size = 24; + this->subtitle_size = 1; + + this->font = class->xine->config->register_string(class->xine->config, + "subtitles.separate.font", + "sans", + _("font for external subtitles"), + NULL, 0, update_osd_font, this); + + this->vertical_offset = class->xine->config->register_num(class->xine->config, + "subtitles.separate.vertical_offset", + 0, + _("subtitle vertical offset (relative window size)"), + NULL, 0, update_vertical_offset, this); + + this->current_anchor.href = NULL; + + lprintf ("video_out is at %p\n", this->stream->video_out); + + return (spu_decoder_t *) this; +} + +static void update_src_encoding(void *this_gen, xine_cfg_entry_t *entry) +{ + spucmml_class_t *this = (spucmml_class_t *)this_gen; + + this->src_encoding = entry->str_value; + printf("libspucmml: spu_src_encoding = %s\n", this->src_encoding ); +} + +static void *init_spu_decoder_plugin (xine_t *xine, void *data) { + + spucmml_class_t *this ; + + this = (spucmml_class_t *) xine_xmalloc (sizeof (spucmml_class_t)); + + this->class.open_plugin = spucmml_class_open_plugin; + this->class.identifier = "spucmml"; + this->class.description = N_("CMML subtitle decoder plugin"); + this->class.dispose = default_spu_decoder_class_dispose; + + this->xine = xine; + + this->src_encoding = xine->config->register_string(xine->config, + "subtitles.separate.src_encoding", + "iso-8859-1", + _("encoding of subtitles"), + NULL, 10, update_src_encoding, this); + + return &this->class; +} + + +/* plugin catalog information */ +static uint32_t supported_types[] = { BUF_SPU_CMML, 0 }; + +static const decoder_info_t spudec_info = { + supported_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_SPU_DECODER, 17, "spucmml", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + diff --git a/src/spu_dec/nav_read.c b/src/spu_dec/nav_read.c new file mode 100644 index 000000000..5244bfdd6 --- /dev/null +++ b/src/spu_dec/nav_read.c @@ -0,0 +1 @@ +#include "../input/libdvdnav/nav_read.c" diff --git a/src/spu_dec/spu_decoder.c b/src/spu_dec/spu_decoder.c new file mode 100644 index 000000000..e36b39fc8 --- /dev/null +++ b/src/spu_dec/spu_decoder.c @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 + * + * This file is part of xine, a unix 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * stuff needed to turn libspu into a xine decoder plugin + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "xine-engine/bswap.h" +#include +#ifdef HAVE_DVDNAV +# include +# include +#else +# include "nav_read.h" +# include "nav_types.h" +#endif + +#include "spudec.h" + +/* +#define LOG_DEBUG 1 +#define LOG_BUTTON 1 +*/ + +static const clut_t default_clut[] = { + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), + CLUT_Y_CR_CB_INIT(0x51, 0xef, 0x5a), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x36, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x51, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), + CLUT_Y_CR_CB_INIT(0x5c, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x1c, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef) +}; + +static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { + uint32_t stream_id; + spudec_seq_t *cur_seq; + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + stream_id = buf->type & 0x1f ; + cur_seq = &this->spudec_stream_state[stream_id].ra_seq; + +#ifdef LOG_DEBUG + printf("libspudec:got buffer type = %x\n", buf->type); +#endif + + /* check, if we need to process the next PCI from the list */ + pthread_mutex_lock(&this->nav_pci_lock); + spudec_update_nav(this); + pthread_mutex_unlock(&this->nav_pci_lock); + + if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || + !(buf->decoder_flags & BUF_FLAG_SPECIAL) || + buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) + return; + + if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_CLUT ) { +#ifdef LOG_DEBUG + printf("libspudec: SPU CLUT\n"); +#endif + if (buf->content[0]) { /* cheap endianess detection */ + xine_fast_memcpy(this->state.clut, buf->content, sizeof(uint32_t)*16); + } else { + int i; + uint32_t *clut = (uint32_t*) buf->content; + for (i = 0; i < 16; i++) + this->state.clut[i] = bswap_32(clut[i]); + } + this->state.need_clut = 0; + return; + } + + if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV ) { +#ifdef LOG_DEBUG + printf("libspudec:got nav packet 1\n"); +#endif + spudec_decode_nav(this,buf); + return; + } + + if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_VOBSUB_PACKAGE ) { + this->state.vobsub = 1; + } + +#ifdef LOG_DEBUG + printf("libspudec:got buffer type = %x\n", buf->type); +#endif + if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */ + return; + + if (buf->pts) { + metronom_t *metronom = this->stream->metronom; + int64_t vpts = metronom->got_spu_packet(metronom, buf->pts); + + this->spudec_stream_state[stream_id].vpts = vpts; /* Show timer */ + this->spudec_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */ + } + + spudec_reassembly(this->stream->xine, + &this->spudec_stream_state[stream_id].ra_seq, buf->content, buf->size); + if(this->spudec_stream_state[stream_id].ra_seq.complete == 1) { + if(this->spudec_stream_state[stream_id].ra_seq.broken) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); + this->spudec_stream_state[stream_id].ra_seq.broken = 0; + } else + spudec_process(this,stream_id); + } +} + +static void spudec_reset (spu_decoder_t *this_gen) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + int i; + + if( this->menu_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->menu_handle); + this->menu_handle = -1; + + for (i=0; i < MAX_STREAMS; i++) { + if( this->spudec_stream_state[i].overlay_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->spudec_stream_state[i].overlay_handle); + this->spudec_stream_state[i].overlay_handle = -1; + this->spudec_stream_state[i].ra_seq.complete = 1; + this->spudec_stream_state[i].ra_seq.broken = 0; + } + + pthread_mutex_lock(&this->nav_pci_lock); + spudec_clear_nav_list(this); + pthread_mutex_unlock(&this->nav_pci_lock); +} + +static void spudec_discontinuity (spu_decoder_t *this_gen) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + + pthread_mutex_lock(&this->nav_pci_lock); + spudec_clear_nav_list(this); + pthread_mutex_unlock(&this->nav_pci_lock); +} + + +static void spudec_dispose (spu_decoder_t *this_gen) { + + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + int i; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + + if( this->menu_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->menu_handle); + this->menu_handle = -1; + + for (i=0; i < MAX_STREAMS; i++) { + if( this->spudec_stream_state[i].overlay_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->spudec_stream_state[i].overlay_handle); + this->spudec_stream_state[i].overlay_handle = -1; + free (this->spudec_stream_state[i].ra_seq.buf); + } + + spudec_clear_nav_list(this); + pthread_mutex_destroy(&this->nav_pci_lock); + + free (this->event.object.overlay); + free (this); +} + +/* gets the current already correctly processed nav_pci info */ +/* This is not perfectly in sync with the display, but all the same, */ +/* much closer than doing it at the input stage. */ +/* returns a bool for error/success.*/ +static int spudec_get_interact_info (spu_decoder_t *this_gen, void *data) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + /*printf("get_interact_info() called\n");*/ + if (!this || !data) + return 0; + + /*printf("get_interact_info() coping nav_pci\n");*/ + pthread_mutex_lock(&this->nav_pci_lock); + spudec_update_nav(this); + memcpy(data, &this->pci_cur.pci, sizeof(pci_t) ); + pthread_mutex_unlock(&this->nav_pci_lock); + return 1; + +} + +static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t show) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + /* This function will move to video_overlay + * when video_overlay does menus */ + + video_overlay_manager_t *ovl_manager; + video_overlay_event_t *overlay_event = NULL; + vo_overlay_t *overlay = NULL; + overlay_event = xine_xmalloc (sizeof(video_overlay_event_t)); + + overlay = xine_xmalloc (sizeof(vo_overlay_t)); + /* FIXME: Watch out for threads. We should really put a lock on this + * because events is a different thread than decode_data */ + + if( this->menu_handle < 0 ) { + if (this->stream->video_out) { + ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + this->menu_handle = ovl_manager->get_handle(ovl_manager,1); + } + } +#ifdef LOG_BUTTON + printf ("libspudec:xine_decoder.c:spudec_event_listener:this=%p\n",this); + printf ("libspudec:xine_decoder.c:spudec_event_listener:this->menu_handle=%d\n",this->menu_handle); +#endif + if(this->menu_handle < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "Menu handle alloc failed. No more overlays objects available. Only %d at once please.", + MAX_OBJECTS); + free(overlay_event); + free(overlay); + return; + } + + if (show > 0) { +#ifdef LOG_NAV + fprintf (stderr,"libspudec:xine_decoder.c:spudec_event_listener:buttonN = %u show=%d\n", + button, + show); +#endif + this->buttonN = button; + if (this->button_filter != 1) { +#ifdef LOG_BUTTON + fprintf (stdout,"libspudec:xine_decoder.c:spudec_event_listener:buttonN updates not allowed\n"); +#endif + /* Only update highlight is the menu will let us */ + free(overlay_event); + free(overlay); + return; + } + if (show == 2) { + this->button_filter = 2; + } + pthread_mutex_lock(&this->nav_pci_lock); + spudec_update_nav(this); + overlay_event->object.handle = this->menu_handle; + overlay_event->object.pts = this->pci_cur.pci.hli.hl_gi.hli_s_ptm; + overlay_event->object.overlay=overlay; + overlay_event->event_type = OVERLAY_EVENT_MENU_BUTTON; +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec:Button Overlay\n"); +#endif + spudec_copy_nav_to_overlay(this->stream->xine, &this->pci_cur.pci, this->state.clut, + this->buttonN, show-1, overlay, &this->overlay ); + pthread_mutex_unlock(&this->nav_pci_lock); + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec:xine_decoder.c:spudec_event_listener:HIDE ????\n"); + printf("We dropped out here for some reason"); + _x_abort(); + overlay_event->object.handle = this->menu_handle; + overlay_event->event_type = OVERLAY_EVENT_HIDE; + } + overlay_event->vpts = 0; + if (this->stream->video_out) { + ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", + overlay_event->event_type, + this->stream->xine->clock->get_current_time(this->stream->xine->clock), + overlay_event->vpts); +#endif + ovl_manager->add_event (ovl_manager, (void *)overlay_event); + free(overlay_event); + free(overlay); + } else { + free(overlay_event); + free(overlay); + } + return; +} + +static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { + + spudec_decoder_t *this ; + int i; + + this = (spudec_decoder_t *) xine_xmalloc (sizeof (spudec_decoder_t)); + + this->spu_decoder.decode_data = spudec_decode_data; + this->spu_decoder.reset = spudec_reset; + this->spu_decoder.discontinuity = spudec_discontinuity; + this->spu_decoder.dispose = spudec_dispose; + this->spu_decoder.get_interact_info = spudec_get_interact_info; + this->spu_decoder.set_button = spudec_set_button; + this->stream = stream; + this->class = (spudec_class_t *) class_gen; + + this->menu_handle = -1; + this->buttonN = 1; + this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t)); + + pthread_mutex_init(&this->nav_pci_lock, NULL); + this->pci_cur.pci.hli.hl_gi.hli_ss = 0; + this->pci_cur.next = NULL; + + this->ovl_caps = stream->video_out->get_capabilities(stream->video_out); + this->output_open = 0; + this->last_event_vpts = 0; + for (i=0; i < MAX_STREAMS; i++) { + this->spudec_stream_state[i].ra_seq.complete = 1; + this->spudec_stream_state[i].overlay_handle = -1; + } + +/* FIXME:Do we really need a default clut? */ + xine_fast_memcpy(this->state.clut, default_clut, sizeof(this->state.clut)); + this->state.need_clut = 1; + this->state.vobsub = 0; + + return &this->spu_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + spudec_class_t *this; + + this = (spudec_class_t *) xine_xmalloc (sizeof (spudec_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "spudec"; + this->decoder_class.description = N_("DVD/VOB SPU decoder plugin"); + this->decoder_class.dispose = default_spu_decoder_class_dispose; + + lprintf ("libspudec:init_plugin called\n"); + return this; +} + +/* plugin catalog information */ +static uint32_t supported_types[] = { BUF_SPU_DVD, 0 }; + +static const decoder_info_t dec_info_data = { + supported_types, /* supported types */ + 5 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_SPU_DECODER, 17, "spudec", XINE_VERSION_CODE, &dec_info_data, &init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/spu_dec/spudec.c b/src/spu_dec/spudec.c new file mode 100644 index 000000000..13136a53f --- /dev/null +++ b/src/spu_dec/spudec.c @@ -0,0 +1,1026 @@ +/* + * Copyright (C) 2002-2004 the xine project + * + * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 + * + * spu.c - converts DVD subtitles to an XPM image + * + * Mostly based on hard work by: + * + * Copyright (C) 2000 Samuel Hocevar + * and Michel Lespinasse + * + * Lots of rearranging by: + * Aaron Holtzman + * Thomas Mirlacher + * implemented reassembling + * cleaner implementation of SPU are saving + * overlaying (proof of concept for now) + * ... and yes, it works now with oms + * added tranparency (provided by the SPU hdr) + * changed structures for easy porting to MGAs DVD mode + * This file is part of xine + * This file was originally part of the OMS program. + * + * This program 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, or (at your option) + * any later version. + * + * This program 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "xine-engine/bswap.h" +#ifdef HAVE_DVDNAV +# include +# include +#else +# include "nav_read.h" +# include "nav_print.h" +#endif + +#include "spudec.h" + +/* +#define LOG_DEBUG 1 +#define LOG_BUTTON 1 +#define LOG_NAV 1 +*/ + +static void spudec_do_commands (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); +static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl); +static void spudec_discover_clut (xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl); +#ifdef LOG_DEBUG +static void spudec_print_overlay( vo_overlay_t *overlay ); +#endif + +void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) { + uint8_t *p; + uint32_t packet_len; + uint32_t stream_id; + uint32_t header_len; + pci_t pci; + dsi_t dsi; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + + p = buf->content; + if (p[0] || p[1] || (p[2] != 1)) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec:spudec_decode_nav:nav demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); + return; + } + + packet_len = p[4] << 8 | p[5]; + stream_id = p[3]; + + header_len = 6; + p += header_len; + + if (stream_id == 0xbf) { /* Private stream 2 */ +/* int i; + * for(i=0;i<80;i++) { + * printf("%02x ",p[i]); + * } + * printf("\n p[0]=0x%02x\n",p[0]); + */ + if(p[0] == 0x00) { +#ifdef LOG_NAV + printf("libspudec:nav_PCI\n"); +#endif + navRead_PCI(&pci, p+1); +#ifdef LOG_NAV + printf("libspudec:nav:hli_ss=%u, hli_s_ptm=%u, hli_e_ptm=%u, btn_sl_e_ptm=%u pts=%lli\n", + pci.hli.hl_gi.hli_ss, + pci.hli.hl_gi.hli_s_ptm, + pci.hli.hl_gi.hli_e_ptm, + pci.hli.hl_gi.btn_se_e_ptm, + buf->pts); + printf("libspudec:nav:btn_sn/ofn=%u, btn_ns=%u, fosl_btnn=%u, foac_btnn=%u\n", + pci.hli.hl_gi.btn_ofn, pci.hli.hl_gi.btn_ns, + pci.hli.hl_gi.fosl_btnn, pci.hli.hl_gi.foac_btnn); + printf("btngr_ns %d\n", pci.hli.hl_gi.btngr_ns); + printf("btngr%d_dsp_ty 0x%02x\n", 1, pci.hli.hl_gi.btngr1_dsp_ty); + printf("btngr%d_dsp_ty 0x%02x\n", 2, pci.hli.hl_gi.btngr2_dsp_ty); + printf("btngr%d_dsp_ty 0x%02x\n", 3, pci.hli.hl_gi.btngr3_dsp_ty); + //navPrint_PCI(&pci); + //navPrint_PCI_GI(&pci.pci_gi); + //navPrint_NSML_AGLI(&pci.nsml_agli); + //navPrint_HLI(&pci.hli); + //navPrint_HL_GI(&pci.hli.hl_gi, & btngr_ns, & btn_ns); +#endif + } + + p += packet_len; + + /* We should now have a DSI packet. */ + /* We don't need anything from the DSI packet here. */ + if(p[6] == 0x01) { + packet_len = p[4] << 8 | p[5]; + p += 6; +#ifdef LOG_NAV + printf("NAV DSI packet\n"); +#endif + navRead_DSI(&dsi, p+1); + +// self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; +// self->vobu_length = self->dsi.dsi_gi.vobu_ea; + } + } + + /* NAV packets contain start and end presentation timestamps, which tell the + * application, when the highlight information in the NAV is supposed to be valid. + * We handle these timestamps only in a very stripped-down way: We keep a list + * of NAV packets (or better: the PCI part of them), tagged with a VPTS timestamp + * telling, when the NAV should be processed. However, we only enqueue a new node + * into this list, when we receive new highlight information during an already + * showing menu. This happens very rarerly on common DVDs, so it is of low impact. + * And we only check for processing of queued entries at some prominent + * locations in this SPU decoder. Since presentation timestamps rarely solve a real + * purpose on most DVDs, this is ok compared to the full-blown solution, which would + * require a separate thread managing the queue all the time. */ + pthread_mutex_lock(&this->nav_pci_lock); + switch (pci.hli.hl_gi.hli_ss) { + case 0: + /* No Highlight information for this VOBU */ + if ( this->pci_cur.pci.hli.hl_gi.hli_ss == 1) { + /* Hide menu spu between menus */ +#ifdef LOG_BUTTON + printf("libspudec:nav:SHOULD HIDE SPU here\n"); +#endif + if( this->menu_handle < 0 ) { + this->menu_handle = ovl_manager->get_handle(ovl_manager,1); + } + if( this->menu_handle >= 0 ) { + this->event.object.handle = this->menu_handle; + this->event.event_type = OVERLAY_EVENT_HIDE; + /* hide menu right now */ + this->event.vpts = 0; + ovl_manager->add_event(ovl_manager, (void *)&this->event); + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: No video_overlay handles left for menu\n"); + } + } + spudec_clear_nav_list(this); + xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); + /* incoming SPUs will be plain subtitles */ + this->event.object.object_type = 0; + if (this->button_filter) { + /* we possibly had buttons before, so we update the UI info */ + xine_event_t event; + xine_ui_data_t data; + + event.type = XINE_EVENT_UI_NUM_BUTTONS; + event.data = &data; + event.data_length = sizeof(data); + data.num_buttons = 0; + + xine_event_send(this->stream, &event); + } + this->button_filter=0; + + break; + case 1: + /* All New Highlight information for this VOBU */ + if (this->pci_cur.pci.hli.hl_gi.hli_ss != 0 && + pci.hli.hl_gi.hli_s_ptm > this->pci_cur.pci.hli.hl_gi.hli_s_ptm) { + pci_node_t *node = &this->pci_cur; +#ifdef LOG_DEBUG + printf("libspudec: allocating new PCI node for hli_s_ptm %d\n", pci.hli.hl_gi.hli_s_ptm); +#endif + /* append PCI at the end of the list */ + while (node->next) node = node->next; + node->next = (pci_node_t *)xine_xmalloc(sizeof(pci_node_t)); + node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm); + node->next->next = NULL; + xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t)); + } else { + spudec_clear_nav_list(this); + /* menu ahead, remember PCI for later use */ + xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); + spudec_process_nav(this); + } + break; + case 2: + /* Use Highlight information from previous VOBU */ + if (this->pci_cur.next) { + /* apply changes to last enqueued NAV */ + pci_node_t *node = this->pci_cur.next; + while (node->next) node = node->next; + node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + spudec_update_nav(this); + } else { + this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + } + break; + case 3: + /* Use Highlight information from previous VOBU except commands, which come from this VOBU */ + if (this->pci_cur.next) { + /* apply changes to last enqueued NAV */ + pci_node_t *node = this->pci_cur.next; + while (node->next) node = node->next; + node->pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + node->pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + node->pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + /* FIXME: Add command copying here */ + spudec_update_nav(this); + } else { + this->pci_cur.pci.pci_gi.vobu_s_ptm = pci.pci_gi.vobu_s_ptm; + this->pci_cur.pci.pci_gi.vobu_e_ptm = pci.pci_gi.vobu_e_ptm; + this->pci_cur.pci.pci_gi.vobu_se_e_ptm = pci.pci_gi.vobu_se_e_ptm; + /* FIXME: Add command copying here */ + } + break; + default: + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec: unknown pci.hli.hl_gi.hli_ss = %d\n", pci.hli.hl_gi.hli_ss ); + break; + } + pthread_mutex_unlock(&this->nav_pci_lock); + return; +} + +void spudec_clear_nav_list(spudec_decoder_t *this) +{ + while (this->pci_cur.next) { + pci_node_t *node = this->pci_cur.next->next; + free(this->pci_cur.next); + this->pci_cur.next = node; + } + /* invalidate current timestamp */ + this->pci_cur.pci.hli.hl_gi.hli_s_ptm = (uint32_t)-1; +} + +void spudec_update_nav(spudec_decoder_t *this) +{ + metronom_clock_t *clock = this->stream->xine->clock; + + if (this->pci_cur.next && this->pci_cur.next->vpts <= clock->get_current_time(clock)) { + pci_node_t *node = this->pci_cur.next; + xine_fast_memcpy(&this->pci_cur, this->pci_cur.next, sizeof(pci_node_t)); + spudec_process_nav(this); + free(node); + } +} + +void spudec_process_nav(spudec_decoder_t *this) +{ + /* incoming SPUs will be menus */ + this->event.object.object_type = 1; + if (!this->button_filter) { + /* we possibly entered a menu, so we update the UI button info */ + xine_event_t event; + xine_ui_data_t data; + + event.type = XINE_EVENT_UI_NUM_BUTTONS; + event.data = &data; + event.data_length = sizeof(data); + data.num_buttons = this->pci_cur.pci.hli.hl_gi.btn_ns; + + xine_event_send(this->stream, &event); + } + this->button_filter=1; +} + +void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len) +{ +#ifdef LOG_DEBUG + printf ("libspudec: seq->complete = %d\n", seq->complete); + printf("libspudec:1: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", + seq->ra_offs, + seq->seq_len, + seq->buf_len, + seq->buf); +#endif + if (seq->complete) { + seq->seq_len = (((uint32_t)pkt_data[0])<<8) | pkt_data[1]; + seq->cmd_offs = (((uint32_t)pkt_data[2])<<8) | pkt_data[3]; + if (seq->cmd_offs >= seq->seq_len) { + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); + seq->broken = 1; + } + if (seq->buf_len < seq->seq_len) { + seq->buf_len = seq->seq_len; +#ifdef LOG_DEBUG + printf ("spu: MALLOC1: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); +#endif + if (seq->buf) { + free(seq->buf); + seq->buf = NULL; + } + seq->buf = malloc(seq->buf_len); +#ifdef LOG_DEBUG + printf ("spu: MALLOC2: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); +#endif + + } + seq->ra_offs = 0; + +#ifdef LOG_DEBUG + printf ("spu: buf_len: %d\n", seq->buf_len); + printf ("spu: cmd_off: %d\n", seq->cmd_offs); +#endif + } + +#ifdef LOG_DEBUG + printf("libspudec:2: seq->ra_offs = %d, seq->seq_len = %d, seq->buf_len = %d, seq->buf=%p\n", + seq->ra_offs, + seq->seq_len, + seq->buf_len, + seq->buf); +#endif + if (seq->ra_offs < seq->seq_len) { + if (seq->ra_offs + pkt_len > seq->seq_len) + pkt_len = seq->seq_len - seq->ra_offs; + memcpy (seq->buf + seq->ra_offs, pkt_data, pkt_len); + seq->ra_offs += pkt_len; + } else { + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); + seq->broken = 1; + } + + if (seq->ra_offs == seq->seq_len) { + seq->finished = 0; + seq->complete = 1; + return; /* sequence ready */ + } + seq->complete = 0; + return; +} + +void spudec_process (spudec_decoder_t *this, int stream_id) { + spudec_seq_t *cur_seq; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + int pending = 1; + cur_seq = &this->spudec_stream_state[stream_id].ra_seq; + +#ifdef LOG_DEBUG + printf ("spu: Found SPU from stream %d pts=%lli vpts=%lli\n",stream_id, + this->spudec_stream_state[stream_id].pts, + this->spudec_stream_state[stream_id].vpts); +#endif + this->state.cmd_ptr = cur_seq->buf + cur_seq->cmd_offs; + this->state.modified = 1; /* Only draw picture if = 1 on first event of SPU */ + this->state.visible = OVERLAY_EVENT_SHOW; + this->state.forced_display = 0; /* 0 - No value, 1 - Forced Display. */ + this->state.delay = 0; + cur_seq->finished=0; + + do { + if (!(cur_seq->finished) ) { + pci_node_t *node; + + /* spu_channel is now set based on whether we are in the menu or not. */ + /* Bit 7 is set if only forced display SPUs should be shown */ + if ( (this->stream->spu_channel & 0x1f) != stream_id ) { +#ifdef LOG_DEBUG + printf ("spu: Dropping SPU channel %d. Not selected stream_id\n", stream_id); +#endif + return; + } + /* parse SPU command sequence, this will update forced_display, so it must come + * before the check for it */ + spudec_do_commands(this->stream->xine, &this->state, cur_seq, &this->overlay); + /* FIXME: Check for Forced-display or subtitle stream + * For subtitles, open event. + * For menus, store it for later. + */ + if (cur_seq->broken) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); + cur_seq->broken = 0; + return; + } + if ( (this->state.forced_display == 0) && (this->stream->spu_channel & 0x80) ) { +#ifdef LOG_DEBUG + printf ("spu: Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id); +#endif + return; + } + +#ifdef LOG_DEBUG + spudec_print_overlay( &this->overlay ); + printf ("spu: forced display:%s\n", this->state.forced_display ? "Yes" : "No" ); +#endif + pthread_mutex_lock(&this->nav_pci_lock); + /* search for a PCI that matches this SPU's PTS */ + for (node = &this->pci_cur; node; node = node->next) + if (node->pci.hli.hl_gi.hli_s_ptm == this->spudec_stream_state[stream_id].pts) + break; + if (node) { + if (this->state.visible == OVERLAY_EVENT_HIDE) { + /* menus are hidden via nav packet decoding, not here */ + /* FIXME: James is not sure about this solution and may want to look this over. + * I'm commiting it, because I haven't found a disc it breaks, but it fixes + * some instead. Michael Roitzsch */ + pthread_mutex_unlock(&this->nav_pci_lock); + continue; + } + if (node->pci.hli.hl_gi.fosl_btnn > 0) { + xine_event_t event; + + this->buttonN = node->pci.hli.hl_gi.fosl_btnn; + event.type = XINE_EVENT_INPUT_BUTTON_FORCE; + event.stream = this->stream; + event.data = &this->buttonN; + event.data_length = sizeof(this->buttonN); + xine_event_send(this->stream, &event); + } +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec:Full Overlay\n"); +#endif + if (!spudec_copy_nav_to_overlay(this->stream->xine, + &node->pci, this->state.clut, + this->buttonN, 0, &this->overlay, &this->overlay)) { + /* current button does not exist -> use another one */ + xine_event_t event; + + if (this->buttonN > node->pci.hli.hl_gi.btn_ns) + this->buttonN = node->pci.hli.hl_gi.btn_ns; + else + this->buttonN = 1; + event.type = XINE_EVENT_INPUT_BUTTON_FORCE; + event.stream = this->stream; + event.data = &this->buttonN; + event.data_length = sizeof(this->buttonN); + xine_event_send(this->stream, &event); + spudec_copy_nav_to_overlay(this->stream->xine, + &node->pci, this->state.clut, + this->buttonN, 0, &this->overlay, &this->overlay); + } + } else { + /* Subtitle and not a menu button */ + int i; + for (i = 0;i < 4; i++) { + this->overlay.hili_color[i] = this->overlay.color[i]; + this->overlay.hili_trans[i] = this->overlay.trans[i]; + } + } + pthread_mutex_unlock(&this->nav_pci_lock); + + if ((this->state.modified) ) { + spudec_draw_picture(this->stream->xine, &this->state, cur_seq, &this->overlay); + } + + if (this->state.need_clut) { + spudec_discover_clut(this->stream->xine, &this->state, &this->overlay); + } + + if (this->state.vobsub) { + int width, height; + int64_t duration; + + /* + * vobsubs are usually played with a scaled-down stream (not full DVD + * resolution), therefore we should try to realign it. + */ + + this->stream->video_out->status(this->stream->video_out, NULL, + &width, &height, &duration ); + + this->overlay.x = (width - this->overlay.width) / 2; + this->overlay.y = height - this->overlay.height; + } + + /* Subtitle */ + if( this->menu_handle < 0 ) { + this->menu_handle = ovl_manager->get_handle(ovl_manager,1); + } + + if( this->menu_handle < 0 ) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec: No video_overlay handles left for menu\n"); + return; + } + this->event.object.handle = this->menu_handle; + this->event.object.pts = this->spudec_stream_state[stream_id].pts; + + xine_fast_memcpy(this->event.object.overlay, + &this->overlay, + sizeof(vo_overlay_t)); + this->overlay.rle=NULL; + /* For force display menus */ + //if ( !(this->state.visible) ) { + // this->state.visible = OVERLAY_EVENT_SHOW; + //} + + this->event.event_type = this->state.visible; + /* + printf("spu event %d handle: %d vpts: %lli\n", this->event.event_type, + this->event.object.handle, this->event.vpts ); + */ + + this->event.vpts = this->spudec_stream_state[stream_id].vpts+(this->state.delay*1000); + + /* Keep all the events in the correct order. */ + /* This corrects for errors during estimation around discontinuity */ + if( this->event.vpts < this->last_event_vpts ) { + this->event.vpts = this->last_event_vpts + 1; + } + this->last_event_vpts = this->event.vpts; + +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", + this->event.event_type, + this->stream->xine->clock->get_current_time(this->stream->xine->clock), + this->event.vpts); +#endif + ovl_manager->add_event(ovl_manager, (void *)&this->event); + } else { + pending = 0; + } + } while (pending); + +} + +#define CMD_SPU_FORCE_DISPLAY 0x00 +#define CMD_SPU_SHOW 0x01 +#define CMD_SPU_HIDE 0x02 +#define CMD_SPU_SET_PALETTE 0x03 +#define CMD_SPU_SET_ALPHA 0x04 +#define CMD_SPU_SET_SIZE 0x05 +#define CMD_SPU_SET_PXD_OFFSET 0x06 +#define CMD_SPU_WIPE 0x07 /* Not currently implemented */ +#define CMD_SPU_EOF 0xff + +static void spudec_do_commands(xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) +{ + uint8_t *buf = state->cmd_ptr; + uint8_t *next_seq; + int32_t param_length; + +#ifdef LOG_DEBUG + printf ("spu: SPU DO COMMANDS\n"); +#endif + + state->delay = (buf[0] << 8) + buf[1]; +#ifdef LOG_DEBUG + printf ("spu: \tdelay=%d\n",state->delay); +#endif + next_seq = seq->buf + (buf[2] << 8) + buf[3]; + buf += 4; +#ifdef LOG_DEBUG + printf ("spu: \tnext_seq=%d\n",next_seq - seq->buf); +#endif + +/* if next equals current, this is the last one + */ + if (state->cmd_ptr >= next_seq) + next_seq = seq->buf + seq->seq_len; /* allow to run until end */ + + state->cmd_ptr = next_seq; + + while (buf < next_seq && *buf != CMD_SPU_EOF) { + switch (*buf) { + case CMD_SPU_SHOW: /* show subpicture */ +#ifdef LOG_DEBUG + printf ("spu: \tshow subpicture\n"); +#endif + state->visible = OVERLAY_EVENT_SHOW; + buf++; + break; + + case CMD_SPU_HIDE: /* hide subpicture */ +#ifdef LOG_DEBUG + printf ("spu: \thide subpicture\n"); +#endif + state->visible = OVERLAY_EVENT_HIDE; + buf++; + break; + + case CMD_SPU_SET_PALETTE: { /* CLUT */ + spudec_clut_t *clut = (spudec_clut_t *) (buf+1); + + state->cur_colors[3] = clut->entry0; + state->cur_colors[2] = clut->entry1; + state->cur_colors[1] = clut->entry2; + state->cur_colors[0] = clut->entry3; + +/* This is a bit out of context for now */ + ovl->color[3] = state->clut[clut->entry0]; + ovl->color[2] = state->clut[clut->entry1]; + ovl->color[1] = state->clut[clut->entry2]; + ovl->color[0] = state->clut[clut->entry3]; + +#ifdef LOG_DEBUG + printf ("spu: \tclut [%x %x %x %x]\n", + ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); + printf ("spu: \tclut base [%x %x %x %x]\n", + clut->entry0, clut->entry1, clut->entry2, clut->entry3); +#endif + state->modified = 1; + buf += 3; + break; + } + case CMD_SPU_SET_ALPHA: { /* transparency palette */ + spudec_clut_t *trans = (spudec_clut_t *) (buf+1); +/* This should go into state for now */ + + ovl->trans[3] = trans->entry0; + ovl->trans[2] = trans->entry1; + ovl->trans[1] = trans->entry2; + ovl->trans[0] = trans->entry3; + +#ifdef LOG_DEBUG + printf ("spu: \ttrans [%d %d %d %d]\n", + ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); +#endif + state->modified = 1; + buf += 3; + break; + } + + case CMD_SPU_SET_SIZE: /* image coordinates */ +/* state->o_left = (buf[1] << 4) | (buf[2] >> 4); + state->o_right = (((buf[2] & 0x0f) << 8) | buf[3]); + + state->o_top = (buf[4] << 4) | (buf[5] >> 4); + state->o_bottom = (((buf[5] & 0x0f) << 8) | buf[6]); + */ + ovl->x = (buf[1] << 4) | (buf[2] >> 4); + ovl->y = (buf[4] << 4) | (buf[5] >> 4); + ovl->width = (((buf[2] & 0x0f) << 8) | buf[3]) - ovl->x + 1; + ovl->height = (((buf[5] & 0x0f) << 8) | buf[6]) - ovl->y + 1; + ovl->hili_top = -1; + ovl->hili_bottom = -1; + ovl->hili_left = -1; + ovl->hili_right = -1; + +#ifdef LOG_DEBUG + printf ("spu: \tx = %d y = %d width = %d height = %d\n", + ovl->x, ovl->y, ovl->width, ovl->height ); +#endif + state->modified = 1; + buf += 7; + break; + + case CMD_SPU_SET_PXD_OFFSET: /* image top[0] field / image bottom[1] field*/ + state->field_offs[0] = (((u_int)buf[1]) << 8) | buf[2]; + state->field_offs[1] = (((u_int)buf[3]) << 8) | buf[4]; + +#ifdef LOG_DEBUG + printf ("spu: \toffset[0] = %d offset[1] = %d\n", + state->field_offs[0], state->field_offs[1]); +#endif + + if ((state->field_offs[0] >= seq->seq_len) || + (state->field_offs[1] >= seq->seq_len)) { + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec:faulty stream\n"); + seq->broken = 1; + } + state->modified = 1; + buf += 5; + break; + + case CMD_SPU_WIPE: +#ifdef LOG_DEBUG + printf ("libspudec: \tSPU_WIPE not implemented yet\n"); +#endif + param_length = (buf[1] << 8) | (buf[2]); + buf += 1 + param_length; + break; + + case CMD_SPU_FORCE_DISPLAY: +#ifdef LOG_DEBUG + printf ("libspudec: \tForce Display/Menu\n"); +#endif + state->forced_display = 1; + buf++; + break; + + default: + xprintf(xine, XINE_VERBOSITY_DEBUG, "libspudec: unknown seqence command (%02x)\n", buf[0]); + /* FIXME: SPU should be dropped, and buffers resynced */ + buf = next_seq; + seq->broken = 1; + break; + } + } + + if (next_seq >= seq->buf + seq->seq_len) + seq->finished = 1; /* last sub-sequence */ +} + +/* FIXME: Get rid of all these static values */ +static uint8_t *bit_ptr[2]; +static int field; // which field we are currently decoding +static int put_x, put_y; + +static u_int get_bits (u_int bits) +{ + static u_int data; + static u_int bits_left; + u_int ret = 0; + + if (!bits) { /* for realignment to next byte */ + bits_left = 0; + } + + while (bits) { + if (bits > bits_left) { + ret |= data << (bits - bits_left); + bits -= bits_left; + + data = *bit_ptr[field]++; + bits_left = 8; + } else { + bits_left -= bits; + ret |= data >> (bits_left); + data &= (1 << bits_left) - 1; + bits = 0; + } + } + + return ret; +} + +static int spudec_next_line (vo_overlay_t *spu) +{ + get_bits (0); // byte align rle data + + put_x = 0; + put_y++; + field ^= 1; // Toggle fields + + if (put_y >= spu->height) { +#ifdef LOG_DEBUG + printf ("spu: put_y >= spu->height\n"); +#endif + return -1; + } + return 0; +} + +static void spudec_draw_picture (xine_t *xine, spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl) +{ + rle_elem_t *rle; + field = 0; + bit_ptr[0] = seq->buf + state->field_offs[0]; + bit_ptr[1] = seq->buf + state->field_offs[1]; + put_x = put_y = 0; + get_bits (0); /* Reset/init bit code */ + +/* ovl->x = state->o_left; + * ovl->y = state->o_top; + * ovl->width = state->o_right - state->o_left + 1; + * ovl->height = state->o_bottom - state->o_top + 1; + + * ovl->hili_top = 0; + * ovl->hili_bottom = ovl->height - 1; + * ovl->hili_left = 0; + * ovl->hili_right = ovl->width - 1; + */ + + /* allocate for the worst case: + * - both fields running to the very end + * - 2 RLE elements per byte meaning single pixel RLE + */ + ovl->data_size = ((seq->cmd_offs - state->field_offs[0]) + + (seq->cmd_offs - state->field_offs[1])) * 2 * sizeof(rle_elem_t); + + if (ovl->rle) { + xprintf (xine, XINE_VERBOSITY_DEBUG, + "libspudec: spudec_draw_picture: ovl->rle is not empty!!!! It should be!!! " + "You should never see this message.\n"); + free(ovl->rle); + ovl->rle=NULL; + } + ovl->rle = malloc(ovl->data_size); + + state->modified = 0; /* mark as already processed */ + rle = ovl->rle; +#ifdef LOG_DEBUG + printf ("libspudec: Draw RLE=%p\n",rle); +#endif + + while (bit_ptr[1] < seq->buf + seq->cmd_offs) { + u_int len; + u_int vlc; + + vlc = get_bits (4); + if (vlc < 0x0004) { + vlc = (vlc << 4) | get_bits (4); + if (vlc < 0x0010) { + vlc = (vlc << 4) | get_bits (4); + if (vlc < 0x0040) { + vlc = (vlc << 4) | get_bits (4); + } + } + } + + len = vlc >> 2; + + /* if len == 0 -> end sequence - fill to end of line */ + if (len == 0) + len = ovl->width - put_x; + + rle->len = len; + rle->color = vlc & 0x03; + rle++; + put_x += len; + + if (put_x >= ovl->width) { + if (spudec_next_line (ovl) < 0) + break; + } + } + + ovl->num_rle = rle - ovl->rle; + ovl->rgb_clut = 0; + ovl->unscaled = 0; +#ifdef LOG_DEBUG + printf ("spu: Num RLE=%d\n",ovl->num_rle); + printf ("spu: Date size=%d\n",ovl->data_size); + printf ("spu: sizeof RLE=%d\n",sizeof(rle_elem_t)); +#endif +} + +/* Heuristic to discover the colors used by the subtitles + and assign a "readable" pallete to them. + Currently looks for sequence of border-fg-border or + border1-border2-fg-border2-border1. + MINFOUND is the number of ocurrences threshold. +*/ +#define MINFOUND 20 +static void spudec_discover_clut(xine_t *xine, spudec_state_t *state, vo_overlay_t *ovl) +{ + int bg,c; + int seqcolor[10]; + int n,i; + rle_elem_t *rle; + + int found[2][16]; + + static clut_t text_clut[] = { + CLUT_Y_CR_CB_INIT(0x80, 0x90, 0x80), + CLUT_Y_CR_CB_INIT(0x00, 0x90, 0x00), + CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00) + }; + + memset(found,0,sizeof(found)); + rle = ovl->rle; + + /* this seems to be a problem somewhere else, + why rle is null? */ + if( !rle ) + return; + + /* suppose the first and last pixels are bg */ + if( rle[0].color != rle[ovl->num_rle-1].color ) + return; + + bg = rle[0].color; + + i = 0; + for( n = 0; n < ovl->num_rle; n++ ) + { + c = rle[n].color; + + if( c == bg ) + { + if( i == 3 && seqcolor[1] == seqcolor[3] ) + { + found[0][seqcolor[2]]++; + if( found[0][seqcolor[2]] > MINFOUND ) + { + memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[1], + sizeof(clut_t)); + memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[2], + sizeof(clut_t)); + ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; + ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; + state->need_clut = 0; + break; + } + } + if( i == 5 && seqcolor[1] == seqcolor[5] + && seqcolor[2] == seqcolor[4] ) + { + found[1][seqcolor[3]]++; + if( found[1][seqcolor[3]] > MINFOUND ) + { + memcpy(&state->clut[state->cur_colors[seqcolor[1]]], &text_clut[0], + sizeof(clut_t)); + memcpy(&state->clut[state->cur_colors[seqcolor[2]]], &text_clut[1], + sizeof(clut_t)); + memcpy(&state->clut[state->cur_colors[seqcolor[3]]], &text_clut[2], + sizeof(clut_t)); + ovl->color[seqcolor[1]] = state->clut[state->cur_colors[seqcolor[1]]]; + ovl->color[seqcolor[2]] = state->clut[state->cur_colors[seqcolor[2]]]; + ovl->color[seqcolor[3]] = state->clut[state->cur_colors[seqcolor[3]]]; + state->need_clut = 0; + break; + } + } + i = 0; + seqcolor[i] = c; + } + else if ( i < 6 ) + { + i++; + seqcolor[i] = c; + } + } +} + +#ifdef LOG_DEBUG +static void spudec_print_overlay( vo_overlay_t *ovl ) { + printf ("spu: OVERLAY to show\n"); + printf ("spu: \tx = %d y = %d width = %d height = %d\n", + ovl->x, ovl->y, ovl->width, ovl->height ); + printf ("spu: \tclut [%x %x %x %x]\n", + ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); + printf ("spu: \ttrans [%d %d %d %d]\n", + ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); + printf ("spu: \tclip top=%d bottom=%d left=%d right=%d\n", + ovl->hili_top, ovl->hili_bottom, ovl->hili_left, ovl->hili_right); + printf ("spu: \tclip_clut [%x %x %x %x]\n", + ovl->hili_color[0], ovl->hili_color[1], ovl->hili_color[2], ovl->hili_color[3]); + printf ("spu: \thili_trans [%d %d %d %d]\n", + ovl->hili_trans[0], ovl->hili_trans[1], ovl->hili_trans[2], ovl->hili_trans[3]); + return; +} +#endif + +int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, + int32_t button, int32_t mode, vo_overlay_t * overlay, vo_overlay_t * base ) { + btni_t *button_ptr = NULL; + unsigned int btns_per_group; + int i; + + if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) + return 0; + + btns_per_group = 36 / nav_pci->hli.hl_gi.btngr_ns; + + /* choose button group: we can always use a normal 4:3 or widescreen button group + * as long as xine blends the overlay before scaling the image to its aspect */ + if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 1 && !(nav_pci->hli.hl_gi.btngr1_dsp_ty & 6)) + button_ptr = &nav_pci->hli.btnit[0 * btns_per_group + button - 1]; + if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 2 && !(nav_pci->hli.hl_gi.btngr2_dsp_ty & 6)) + button_ptr = &nav_pci->hli.btnit[1 * btns_per_group + button - 1]; + if (!button_ptr && nav_pci->hli.hl_gi.btngr_ns >= 3 && !(nav_pci->hli.hl_gi.btngr3_dsp_ty & 6)) + button_ptr = &nav_pci->hli.btnit[2 * btns_per_group + button - 1]; + if (!button_ptr) { + xprintf(xine, XINE_VERBOSITY_DEBUG, + "libspudec: No suitable menu button group found, using group 1.\n"); + button_ptr = &nav_pci->hli.btnit[button - 1]; + } + + /* button areas in the nav packet are in screen coordinates, + * overlay clipping areas are in overlay coordinates; + * therefore we must subtract the display coordinates of the underlying overlay */ + overlay->hili_left = (button_ptr->x_start > base->x) ? (button_ptr->x_start - base->x) : 0; + overlay->hili_top = (button_ptr->y_start > base->y) ? (button_ptr->y_start - base->y) : 0; + overlay->hili_right = (button_ptr->x_end > base->x) ? (button_ptr->x_end - base->x) : 0; + overlay->hili_bottom = (button_ptr->y_end > base->y) ? (button_ptr->y_end - base->y) : 0; + if(button_ptr->btn_coln != 0) { +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: normal button clut\n"); +#endif + for (i = 0;i < 4; i++) { + overlay->hili_color[i] = clut[0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (16 + 4*i))]; + overlay->hili_trans[i] = 0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (4*i)); + } + } else { +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: abnormal button clut\n"); +#endif + for (i = 0;i < 4; i++) { +#ifdef LOG_BUTTON + printf("libspudec:btn_coln = 0, hili_color = color\n"); +#endif + overlay->hili_color[i] = overlay->color[i]; + overlay->hili_trans[i] = overlay->trans[i]; + } + } + + /* spudec_print_overlay( overlay ); */ +#ifdef LOG_BUTTON + printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n"); +#endif + + return 1; +} diff --git a/src/spu_dec/spudec.h b/src/spu_dec/spudec.h new file mode 100644 index 000000000..1e7d80596 --- /dev/null +++ b/src/spu_dec/spudec.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * This file was originally part of the OMS program. + */ + +#ifndef __SPU_H__ +#define __SPU_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#ifdef HAVE_DVDNAV +# include +#else +# include "nav_types.h" +#endif + +#define NUM_SEQ_BUFFERS 50 +#define MAX_STREAMS 32 + +typedef struct spudec_clut_struct { +#ifdef WORDS_BIGENDIAN + uint8_t entry0 : 4; + uint8_t entry1 : 4; + uint8_t entry2 : 4; + uint8_t entry3 : 4; +#else + uint8_t entry1 : 4; + uint8_t entry0 : 4; + uint8_t entry3 : 4; + uint8_t entry2 : 4; +#endif +} spudec_clut_t; + +typedef struct { + uint8_t *buf; + uint32_t ra_offs; /* reassembly offset */ + uint32_t seq_len; + uint32_t buf_len; + uint32_t cmd_offs; + int64_t pts; /* Base PTS of this sequence */ + int32_t finished; /* Has this control sequence been finished? */ + uint32_t complete; /* Has this reassembly been finished? */ + uint32_t broken; /* this SPU is broken and should be dropped */ +} spudec_seq_t; + +typedef struct { + uint8_t *cmd_ptr; + + uint32_t field_offs[2]; + int32_t b_top, o_top; + int32_t b_bottom, o_bottom; + int32_t b_left, o_left; + int32_t b_right, o_right; + + int32_t modified; /* Was the sub-picture modified? */ + int32_t visible; /* Must the sub-picture be shown? */ + int32_t forced_display; /* This overlay is a menu */ + int32_t delay; /* Delay in 90Khz / 1000 */ + int32_t need_clut; /* doesn't have the right clut yet */ + int32_t cur_colors[4];/* current 4 colors been used */ + int32_t vobsub; /* vobsub must be aligned to bottom */ + + uint32_t clut[16]; +} spudec_state_t; + +typedef struct spudec_stream_state_s { + spudec_seq_t ra_seq; + spudec_state_t state; + int64_t vpts; + int64_t pts; + int32_t overlay_handle; +} spudec_stream_state_t; + +typedef struct { + spu_decoder_class_t decoder_class; +} spudec_class_t; + +typedef struct pci_node_s pci_node_t; +struct pci_node_s { + pci_t pci; + uint64_t vpts; + pci_node_t *next; +}; + +typedef struct spudec_decoder_s { + spu_decoder_t spu_decoder; + + spudec_class_t *class; + xine_stream_t *stream; + spudec_stream_state_t spudec_stream_state[MAX_STREAMS]; + + video_overlay_event_t event; + video_overlay_object_t object; + int32_t menu_handle; + + spudec_state_t state; + + vo_overlay_t overlay; + int ovl_caps; + int output_open; + pthread_mutex_t nav_pci_lock; + pci_node_t pci_cur; + uint32_t buttonN; /* Current button number for highlights */ + int32_t button_filter; /* Allow highlight changes or not */ + int64_t last_event_vpts; +} spudec_decoder_t; + +void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len); +void spudec_process( spudec_decoder_t *this, int stream_id); +/* the nav functions must be called with the nav_pci_lock held */ +void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf); +void spudec_clear_nav_list(spudec_decoder_t *this); +void spudec_update_nav(spudec_decoder_t *this); +void spudec_process_nav(spudec_decoder_t *this); +int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, int32_t button, int32_t mode, + vo_overlay_t * overlay, vo_overlay_t * base ); + +#endif diff --git a/src/spu_dec/spudvb_decoder.c b/src/spu_dec/spudvb_decoder.c new file mode 100644 index 000000000..9008260f7 --- /dev/null +++ b/src/spu_dec/spudvb_decoder.c @@ -0,0 +1,999 @@ +/* + * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * DVB Subtitle decoder (ETS 300 743) + * (c) 2004 Mike Lampard + * based on the application dvbsub by Dave Chapman + * + * TODO: + * - Implement support for teletext based subtitles + */ + +#include "pthread.h" +#include +#include +#include +#include +#define MAX_REGIONS 7 + +/*#define LOG 1*/ + +typedef struct { + int x, y; + unsigned char is_visible; +} visible_region_t; + +typedef struct { + int page_time_out; + int page_version_number; + int page_state; + int page_id; + visible_region_t regions[MAX_REGIONS]; +} page_t; + +typedef struct { + int width, height; + int empty; + int depth; + int CLUT_id; + int objects_start; + int objects_end; + unsigned int object_pos[65536]; + unsigned char *img; + osd_object_t *osd; +} region_t; + +typedef struct { +/* dvbsub stuff */ + int x; + int y; + unsigned int curr_obj; + unsigned int curr_reg[64]; + uint8_t *buf; + int i; + int nibble_flag; + int in_scanline; + page_t page; + region_t regions[MAX_REGIONS]; + clut_t colours[MAX_REGIONS*256]; + unsigned char trans[MAX_REGIONS*256]; +} dvbsub_func_t; + +typedef struct dvb_spu_class_s { + spu_decoder_class_t class; + xine_t *xine; +} dvb_spu_class_t; + +typedef struct dvb_spu_decoder_s { + spu_decoder_t spu_decoder; + + dvb_spu_class_t *class; + xine_stream_t *stream; + + spu_dvb_descriptor_t *spu_descriptor; + + /* dvbsub_osd_mutex should be locked around all calls to this->osd_renderer->show() + and this->osd_renderer->hide() */ + pthread_mutex_t dvbsub_osd_mutex; + + char *pes_pkt; + char *pes_pkt_wrptr; + unsigned int pes_pkt_size; + + uint64_t pts; + uint64_t vpts; + uint64_t end_vpts; + + pthread_t dvbsub_timer_thread; + struct timespec dvbsub_hide_timeout; + pthread_cond_t dvbsub_restart_timeout; + dvbsub_func_t *dvbsub; + int show; +} dvb_spu_decoder_t; + + +static void update_osd(dvb_spu_decoder_t *this, int region_id) +{ + dvbsub_func_t *dvbsub = this->dvbsub; + region_t *reg = &dvbsub->regions[region_id]; + + if ( !reg->img ) { + if ( reg->osd ) { + pthread_mutex_lock( &this->dvbsub_osd_mutex ); + this->stream->osd_renderer->free_object( reg->osd ); + reg->osd = NULL; + pthread_mutex_unlock( &this->dvbsub_osd_mutex ); + } + return; + } + + if ( reg->osd ) { + if ( reg->width!=reg->osd->width || reg->height!=reg->osd->height ) { + pthread_mutex_lock( &this->dvbsub_osd_mutex ); + this->stream->osd_renderer->free_object( reg->osd ); + reg->osd = NULL; + pthread_mutex_unlock( &this->dvbsub_osd_mutex ); + } + } + + if ( !reg->osd ) + reg->osd = this->stream->osd_renderer->new_object( this->stream->osd_renderer, reg->width, reg->height ); +} + +static void update_region (dvb_spu_decoder_t * this, int region_id, int region_width, int region_height, int fill, int fill_color) +{ + + dvbsub_func_t *dvbsub = this->dvbsub; + region_t *reg = &dvbsub->regions[region_id]; + page_t *page = &dvbsub->page; + + /* reject invalid sizes and set some limits ! */ + if ( region_width<=0 || region_height<=0 || region_width>720 || region_height>576 ) { + if ( reg->img ) { + free( reg->img ); + reg->img = NULL; + } +#ifdef LOG + printf("SPUDVB: rejected region %d = %dx%d\n", region_id, region_width, region_height ); +#endif + return; + } + + if ( reg->width*reg->heightimg ) { + free( reg->img ); + reg->img = NULL; + } + } + + if ( !reg->img ) { + if ( !(reg->img=xine_xmalloc(region_width*region_height)) ) { + lprintf( "can't allocate mem for region %d\n", region_id ); + return; + } + fill_color = 15; + fill = 1; + } + + if ( fill ) { + memset( reg->img, fill_color, region_width*region_height ); + reg->empty = 1; +#ifdef LOG + printf("SPUDVB : FILL REGION %d\n", region_id); +#endif + } + reg->width = region_width; + reg->height = region_height; + page->regions[region_id].is_visible = 1; +} + + +static void do_plot (dvb_spu_decoder_t * this, int r, int x, int y, unsigned char pixel) +{ + int i; + dvbsub_func_t *dvbsub = this->dvbsub; + + i = (y * dvbsub->regions[r].width) + x; + /* do some clipping */ + if ( i<(dvbsub->regions[r].width*dvbsub->regions[r].height) ) { + dvbsub->regions[r].img[i] = pixel; + dvbsub->regions[r].empty = 0; + } +} + +static void plot (dvb_spu_decoder_t * this, int r, int run_length, unsigned char pixel) +{ + + dvbsub_func_t *dvbsub = this->dvbsub; + + int x2 = dvbsub->x + run_length; + + while (dvbsub->x < x2) { + do_plot (this, r, dvbsub->x, dvbsub->y, pixel); + dvbsub->x++; + } +} + +static unsigned char next_nibble (dvb_spu_decoder_t * this) +{ + unsigned char x; + dvbsub_func_t *dvbsub = this->dvbsub; + + if (dvbsub->nibble_flag == 0) { + x = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + dvbsub->nibble_flag = 1; + } + else { + x = (dvbsub->buf[dvbsub->i++] & 0x0f); + dvbsub->nibble_flag = 0; + } + return (x); +} + +static void decode_4bit_pixel_code_string (dvb_spu_decoder_t * this, int r, int object_id, int ofs, int n) +{ + int next_bits, switch_1, switch_2, switch_3, run_length, pixel_code; + + dvbsub_func_t *dvbsub = this->dvbsub; + + int bits; + unsigned int data; + int j; + + if (dvbsub->in_scanline == 0) { + dvbsub->in_scanline = 1; + } + dvbsub->nibble_flag = 0; + j = dvbsub->i + n; + while (dvbsub->i < j) { + + bits = 0; + pixel_code = 0; + next_bits = next_nibble (this); + + if (next_bits != 0) { + pixel_code = next_bits; + plot (this, r, 1, pixel_code); + bits += 4; + } + else { + bits += 4; + data = next_nibble (this); + switch_1 = (data & 0x08) >> 3; + bits++; + if (switch_1 == 0) { + run_length = (data & 0x07); + bits += 3; + if (run_length != 0) { + plot (this, r, run_length + 2, pixel_code); + } + else { + break; + } + } + else { + switch_2 = (data & 0x04) >> 2; + bits++; + if (switch_2 == 0) { + run_length = (data & 0x03); + bits += 2; + pixel_code = next_nibble (this); + bits += 4; + plot (this, r, run_length + 4, pixel_code); + } + else { + switch_3 = (data & 0x03); + bits += 2; + switch (switch_3) { + case 0: + plot (this, r, 1, pixel_code); + break; + case 1: + plot (this, r, 2, pixel_code); + break; + case 2: + run_length = next_nibble (this); + bits += 4; + pixel_code = next_nibble (this); + bits += 4; + plot (this, r, run_length + 9, pixel_code); + break; + case 3: + run_length = next_nibble (this); + run_length = (run_length << 4) | next_nibble (this); + bits += 8; + pixel_code = next_nibble (this); + bits += 4; + plot (this, r, run_length + 25, pixel_code); + } + } + } + } + + } + if (dvbsub->nibble_flag == 1) { + dvbsub->i++; + dvbsub->nibble_flag = 0; + } +} + +static void recalculate_trans (dvb_spu_decoder_t *this) +{ + dvbsub_func_t *const dvbsub = this->dvbsub; + xine_spu_opacity_t opacity; + int i; + + _x_spu_get_opacity (this->stream->xine, &opacity); + for (i = 0; i < MAX_REGIONS * 256; ++i) { + /* ETSI-300-743 says "full transparency if Y == 0". */ + if (dvbsub->colours[i].y == 0) + dvbsub->trans[i] = 0; + else { + int v = _x_spu_calculate_opacity (&dvbsub->colours[i], dvbsub->colours[i].foo, &opacity); + dvbsub->trans[i] = v * 14 / 255 + 1; + } + } + +} + +static void set_clut(dvb_spu_decoder_t *this,int CLUT_id,int CLUT_entry_id,int Y_value, int Cr_value, int Cb_value, int T_value) { + + dvbsub_func_t *dvbsub = this->dvbsub; + + if ((CLUT_id>=MAX_REGIONS) || (CLUT_entry_id>15)) { + return; + } + + dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].y=Y_value; + dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].cr=Cr_value; + dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].cb=Cb_value; + dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].foo = T_value; +} + +static void process_CLUT_definition_segment(dvb_spu_decoder_t *this) { + int page_id, + segment_length, + CLUT_id, + CLUT_version_number; + + int CLUT_entry_id, + CLUT_flag_8_bit, + CLUT_flag_4_bit, + CLUT_flag_2_bit, + full_range_flag, + Y_value, + Cr_value, + Cb_value, + T_value; + dvbsub_func_t *dvbsub = this->dvbsub; + + int j; + + page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; + segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; + j=dvbsub->i+segment_length; + + CLUT_id=dvbsub->buf[dvbsub->i++]; + CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4; + dvbsub->i++; + + while (dvbsub->i < j) { + CLUT_entry_id=dvbsub->buf[dvbsub->i++]; + + CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7; + CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6; + CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5; + full_range_flag=dvbsub->buf[dvbsub->i]&1; + dvbsub->i++; + + if (full_range_flag==1) { + Y_value=dvbsub->buf[dvbsub->i++]; + Cr_value=dvbsub->buf[dvbsub->i++]; + Cb_value=dvbsub->buf[dvbsub->i++]; + T_value=dvbsub->buf[dvbsub->i++]; + } else { + Y_value = dvbsub->buf[dvbsub->i] & 0xfc; + Cr_value = (dvbsub->buf[dvbsub->i] << 6 | dvbsub->buf[dvbsub->i + 1] >> 2) & 0xf0; + Cb_value = (dvbsub->buf[dvbsub->i + 1] << 2) & 0xf0; + T_value = (dvbsub->buf[dvbsub->i + 1] & 3) * 0x55; /* expand only this one to full range! */ + dvbsub->i+=2; + } + set_clut(this, CLUT_id,CLUT_entry_id,Y_value,Cr_value,Cb_value,T_value); + } +} + +static void process_pixel_data_sub_block (dvb_spu_decoder_t * this, int r, int o, int ofs, int n) +{ + int data_type; + int j; + + dvbsub_func_t *dvbsub = this->dvbsub; + + j = dvbsub->i + n; + + dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16; + dvbsub->y = ((dvbsub->regions[r].object_pos[o]) & 0xffff) + ofs; + while (dvbsub->i < j) { + data_type = dvbsub->buf[dvbsub->i++]; + + switch (data_type) { + case 0: + dvbsub->i++; + case 0x11: + decode_4bit_pixel_code_string (this, r, o, ofs, n - 1); + break; + case 0xf0: + dvbsub->in_scanline = 0; + dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16; + dvbsub->y += 2; + break; + default: + lprintf ("unimplemented data_type %02x in pixel_data_sub_block\n", data_type); + } + } + + dvbsub->i = j; +} + +static void process_page_composition_segment (dvb_spu_decoder_t * this) +{ + int segment_length; + int region_id, region_x, region_y; + int j; + int r; + dvbsub_func_t *dvbsub = this->dvbsub; + + dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + j = dvbsub->i + segment_length; + + dvbsub->page.page_time_out = dvbsub->buf[dvbsub->i++]; + + dvbsub->page.page_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + dvbsub->page.page_state = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; + dvbsub->i++; + if (dvbsub->page.page_state==2) { + for (r=0; rpage.regions[r].is_visible = 0; + } + else if ( dvbsub->page.page_state!=0 && dvbsub->page.page_state!=1 ) { + return; + } + + while (dvbsub->i < j) { + region_id = dvbsub->buf[dvbsub->i++]; + dvbsub->i++; /* reserved */ + region_x = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + region_y = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + dvbsub->page.regions[region_id].x = region_x; + dvbsub->page.regions[region_id].y = region_y; + } +} + + +static void process_region_composition_segment (dvb_spu_decoder_t * this) +{ + int segment_length, + region_id, + region_version_number, + region_fill_flag, region_width, region_height, region_level_of_compatibility, region_depth, CLUT_id, region_8_bit_pixel_code, region_4_bit_pixel_code, region_2_bit_pixel_code; + int object_id, object_type, object_provider_flag, object_x, object_y, foreground_pixel_code, background_pixel_code; + int j; + int o; + dvbsub_func_t *dvbsub = this->dvbsub; + + dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + j = dvbsub->i + segment_length; + + region_id = dvbsub->buf[dvbsub->i++]; + region_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + region_fill_flag = (dvbsub->buf[dvbsub->i] & 0x08) >> 3; + dvbsub->i++; + region_width = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + region_height = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5; + region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2; + dvbsub->i++; + CLUT_id = dvbsub->buf[dvbsub->i++]; + region_8_bit_pixel_code = dvbsub->buf[dvbsub->i++]; + region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; + dvbsub->i++; + + if(region_id>=MAX_REGIONS) + return; + + /* Check if region size has changed and fill background. */ + update_region (this, region_id, region_width, region_height, region_fill_flag, region_4_bit_pixel_code); + if ( CLUT_idregions[region_id].CLUT_id = CLUT_id; + + dvbsub->regions[region_id].objects_start = dvbsub->i; + dvbsub->regions[region_id].objects_end = j; + + for (o = 0; o < 65536; o++) { + dvbsub->regions[region_id].object_pos[o] = 0xffffffff; + } + + while (dvbsub->i < j) { + object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6; + object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4; + object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + dvbsub->regions[region_id].object_pos[object_id] = (object_x << 16) | object_y; + + if ((object_type == 0x01) || (object_type == 0x02)) { + foreground_pixel_code = dvbsub->buf[dvbsub->i++]; + background_pixel_code = dvbsub->buf[dvbsub->i++]; + } + } + +} + +static void process_object_data_segment (dvb_spu_decoder_t * this) +{ + int segment_length, object_id, object_version_number, object_coding_method, non_modifying_colour_flag; + + int top_field_data_block_length, bottom_field_data_block_length; + + dvbsub_func_t *dvbsub = this->dvbsub; + + int j; + int old_i; + int r; + + dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + j = dvbsub->i + segment_length; + + object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + dvbsub->curr_obj = object_id; + object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; + non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1; + dvbsub->i++; + + old_i = dvbsub->i; + for (r = 0; r < MAX_REGIONS; r++) { + + /* If this object is in this region... */ + if (dvbsub->regions[r].img) { + if (dvbsub->regions[r].object_pos[object_id] != 0xffffffff) { + dvbsub->i = old_i; + if (object_coding_method == 0) { + top_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + bottom_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + process_pixel_data_sub_block (this, r, object_id, 0, top_field_data_block_length); + + process_pixel_data_sub_block (this, r, object_id, 1, bottom_field_data_block_length); + } + } + } + } +} + +static void unlock_mutex_cancellation_func(void *mutex_gen) +{ + pthread_mutex_t *mutex = (pthread_mutex_t*) mutex_gen; + pthread_mutex_unlock(mutex); +} + +/* Thread routine that checks for subtitle timeout periodically. + To avoid unexpected subtitle hiding, calls to this->stream->osd_renderer->show() + should be in blocks like: + + pthread_mutex_lock(&this->dvbsub_osd_mutex); + this->stream->osd_renderer->show(...); + this->dvbsub_hide_timeout.tv_sec = time(NULL) + timeout value; + pthread_cond_signal(&this->dvbsub_restart_timeout); + pthread_mutex_unlock(&this->dvbsub_osd_mutex); + + This ensures that the timeout is changed with the lock held, and + that the thread is signalled to pick up the new timeout. +*/ +static void* dvbsub_timer_func(void *this_gen) +{ + dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; + pthread_mutex_lock(&this->dvbsub_osd_mutex); + int i; + + /* If we're cancelled via pthread_cancel, unlock the mutex */ + pthread_cleanup_push(unlock_mutex_cancellation_func, &this->dvbsub_osd_mutex); + + while(1) + { + /* Record the current timeout, and wait - note that pthread_cond_timedwait + will unlock the mutex on entry, and lock it on exit */ + struct timespec timeout = this->dvbsub_hide_timeout; + int result = pthread_cond_timedwait(&this->dvbsub_restart_timeout, + &this->dvbsub_osd_mutex, + &this->dvbsub_hide_timeout); + if(result == ETIMEDOUT && + timeout.tv_sec == this->dvbsub_hide_timeout.tv_sec && + timeout.tv_nsec == this->dvbsub_hide_timeout.tv_nsec) + { + /* We timed out, and no-one changed the timeout underneath us. + Hide the OSD, then wait until we're signalled. */ + if(this && this->stream && this->stream->osd_renderer) + { + for ( i=0; idvbsub->regions[i].osd ) { + this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 ); +#ifdef LOG + printf("SPUDVB: thread hiding = %d\n",i); +#endif + } + } + } + pthread_cond_wait(&this->dvbsub_restart_timeout, &this->dvbsub_osd_mutex); + } + } + + pthread_cleanup_pop(1); + return NULL; +} + +static void downscale_region_image( region_t *reg, unsigned char *dest, int dest_width ) +{ + float i, k, inc=reg->width/(float)dest_width; + int j; + for ( j=0; jheight; j++ ) { + for ( i=0,k=0; iwidth && kimg[(j*reg->width)+(int)i]; + } + } +} + +static void draw_subtitles (dvb_spu_decoder_t * this) +{ + int r; + int display=0; + int64_t dum; + int dest_width=0, dest_height, reg_width; + this->stream->video_out->status(this->stream->video_out, NULL, &dest_width, &dest_height, &dum); + unsigned char tmp[dest_width*576]; + unsigned char *reg; + + if ( !dest_width ) + return; + + /* render all regions onto the page */ + + for ( r=0; rdvbsub->page.regions[r].is_visible ) + display++; + } + if ( !display ) + return; + + for (r = 0; r < MAX_REGIONS; r++) { + if (this->dvbsub->regions[r].img) { + if (this->dvbsub->page.regions[r].is_visible && !this->dvbsub->regions[r].empty) { + update_osd( this, r ); + if ( !this->dvbsub->regions[r].osd ) + continue; + /* clear osd */ + this->stream->osd_renderer->clear( this->dvbsub->regions[r].osd ); + if (this->dvbsub->regions[r].width>dest_width) { + downscale_region_image(&this->dvbsub->regions[r], tmp, dest_width); + reg = tmp; + reg_width = dest_width; + } + else { + reg = this->dvbsub->regions[r].img; + reg_width = this->dvbsub->regions[r].width; + } + this->stream->osd_renderer->set_palette( this->dvbsub->regions[r].osd, (uint32_t*)(&this->dvbsub->colours[this->dvbsub->regions[r].CLUT_id*256]), &this->dvbsub->trans[this->dvbsub->regions[r].CLUT_id*256]); + this->stream->osd_renderer->draw_bitmap( this->dvbsub->regions[r].osd, reg, 0, 0, reg_width, this->dvbsub->regions[r].height, NULL ); + } + } + } + + pthread_mutex_lock(&this->dvbsub_osd_mutex); +#ifdef LOG + printf("SPUDVB: this->vpts=%llu\n",this->vpts); +#endif + for ( r=0; rdvbsub->page.regions[r].is_visible && this->dvbsub->regions[r].osd && !this->dvbsub->regions[r].empty ) { + this->stream->osd_renderer->set_position( this->dvbsub->regions[r].osd, this->dvbsub->page.regions[r].x, this->dvbsub->page.regions[r].y ); + this->stream->osd_renderer->show( this->dvbsub->regions[r].osd, this->vpts ); +#ifdef LOG + printf("SPUDVB: show region = %d\n",r); +#endif + } + else { + if ( this->dvbsub->regions[r].osd ) { + this->stream->osd_renderer->hide( this->dvbsub->regions[r].osd, this->vpts ); +#ifdef LOG + printf("SPUDVB: hide region = %d\n",r); +#endif + } + } + } + this->dvbsub_hide_timeout.tv_nsec = 0; + this->dvbsub_hide_timeout.tv_sec = time(NULL) + this->dvbsub->page.page_time_out; +#ifdef LOG + printf("SPUDVB: page_time_out %d\n",this->dvbsub->page.page_time_out); +#endif + pthread_cond_signal(&this->dvbsub_restart_timeout); + pthread_mutex_unlock(&this->dvbsub_osd_mutex); +} + + +static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf) +{ + dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; + int new_i; + int data_identifier, subtitle_stream_id; + int segment_length, segment_type; + int PES_header_data_length; + int PES_packet_length; + int i; + + if((buf->type & 0xffff0000)!=BUF_SPU_DVB) + return; + + if (buf->decoder_flags & BUF_FLAG_SPECIAL) { + if (buf->decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR) { + if (buf->decoder_info[2] == 0) { + /* Hide the osd - note that if the timeout thread times out, it'll rehide, which is harmless */ + pthread_mutex_lock(&this->dvbsub_osd_mutex); + for ( i=0; idvbsub->regions[i].osd ) + this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 ); + } + pthread_mutex_unlock(&this->dvbsub_osd_mutex); + } + else { + xine_fast_memcpy (this->spu_descriptor, buf->decoder_info_ptr[2], buf->decoder_info[2]); + } + } + return; + } + else { + if (buf->decoder_info[2]) { + memset (this->pes_pkt, 0xff, 64*1024); + this->pes_pkt_wrptr = this->pes_pkt; + this->pes_pkt_size = buf->decoder_info[2]; + this->pts = buf->pts; + + xine_fast_memcpy (this->pes_pkt, buf->content, buf->size); + this->pes_pkt_wrptr += buf->size; + } + else { + if (this->pes_pkt && (this->pes_pkt_wrptr != this->pes_pkt)) { + xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size); + this->pes_pkt_wrptr += buf->size; + } + } + } + /* don't ask metronom for a vpts but rather do the calculation + * because buf->pts could be too far in future and metronom won't accept + * further backwards pts (see metronom_got_spu_packet) */ + if (buf->pts) { + metronom_t *metronom = this->stream->metronom; + int64_t vpts_offset = metronom->get_option( metronom, METRONOM_VPTS_OFFSET ); + int64_t spu_offset = metronom->get_option( metronom, METRONOM_SPU_OFFSET ); + int64_t vpts = (int64_t)(buf->pts)+vpts_offset+spu_offset; + metronom_clock_t *clock = this->stream->xine->clock; + int64_t curvpts = clock->get_current_time( clock ); + /* if buf->pts is unreliable, show page asap (better than nothing) */ +#ifdef LOG + printf("SPUDVB: spu_vpts=%lld - current_vpts=%lld\n", vpts, curvpts); +#endif + if ( vpts<=curvpts || (vpts-curvpts)>(5*90000) ) + this->vpts = 0; + else + this->vpts = vpts; + } + + /* process the pes section */ + + PES_packet_length = this->pes_pkt_size; + + this->dvbsub->buf = this->pes_pkt; + + PES_header_data_length = 0; + this->dvbsub->i = 0; + + data_identifier = this->dvbsub->buf[this->dvbsub->i++]; + subtitle_stream_id = this->dvbsub->buf[this->dvbsub->i++]; + + while (this->dvbsub->i <= (PES_packet_length)) { + /* SUBTITLING SEGMENT */ + this->dvbsub->i++; + segment_type = this->dvbsub->buf[this->dvbsub->i++]; + + this->dvbsub->page.page_id = (this->dvbsub->buf[this->dvbsub->i] << 8) | this->dvbsub->buf[this->dvbsub->i + 1]; + segment_length = (this->dvbsub->buf[this->dvbsub->i + 2] << 8) | this->dvbsub->buf[this->dvbsub->i + 3]; + new_i = this->dvbsub->i + segment_length + 4; + + /* only process complete segments */ + if(new_i > (this->pes_pkt_wrptr - this->pes_pkt)) + break; + /* verify we've the right segment */ + if(this->dvbsub->page.page_id==this->spu_descriptor->comp_page_id){ + /* SEGMENT_DATA_FIELD */ + switch (segment_type & 0xff) { + case 0x10: + process_page_composition_segment (this); + break; + case 0x11: + process_region_composition_segment (this); + break; + case 0x12: + process_CLUT_definition_segment(this); + break; + case 0x13: + process_object_data_segment (this); + break; + case 0x80: /* Page is now completely rendered */ + recalculate_trans(this); + draw_subtitles( this ); + break; + default: + return; + break; + } + } + this->dvbsub->i = new_i; + } + + return; +} + +static void spudec_reset (spu_decoder_t * this_gen) +{ + dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; + int i; + + /* Hide the osd - if the timeout thread times out, it'll rehide harmlessly */ + pthread_mutex_lock(&this->dvbsub_osd_mutex); + for ( i=0; idvbsub->regions[i].osd ) + this->stream->osd_renderer->hide(this->dvbsub->regions[i].osd, 0); + } + pthread_mutex_unlock(&this->dvbsub_osd_mutex); + +} + +static void spudec_discontinuity (spu_decoder_t * this_gen) +{ + /* do nothing */ +} + +static void spudec_dispose (spu_decoder_t * this_gen) +{ + dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; + int i; + + pthread_cancel(this->dvbsub_timer_thread); + pthread_join(this->dvbsub_timer_thread, NULL); + pthread_mutex_destroy(&this->dvbsub_osd_mutex); + pthread_cond_destroy(&this->dvbsub_restart_timeout); + + if(this->spu_descriptor){ + free(this->spu_descriptor); + this->spu_descriptor=NULL; + } + + for ( i=0; idvbsub->regions[i].img ) + free( this->dvbsub->regions[i].img ); + if ( this->dvbsub->regions[i].osd ) + this->stream->osd_renderer->free_object( this->dvbsub->regions[i].osd ); + } + + if (this->pes_pkt) + free (this->pes_pkt); + + if (this->dvbsub) + free (this->dvbsub); + + free (this); +} + +static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream) +{ + + int i; + dvb_spu_decoder_t *this; + dvb_spu_class_t *class = (dvb_spu_class_t *) class_gen; + + this = (dvb_spu_decoder_t *) xine_xmalloc (sizeof (dvb_spu_decoder_t)); + + this->spu_decoder.decode_data = spudec_decode_data; + this->spu_decoder.reset = spudec_reset; + this->spu_decoder.discontinuity = spudec_discontinuity; + this->spu_decoder.dispose = spudec_dispose; + this->spu_decoder.get_interact_info = NULL; + this->spu_decoder.set_button = NULL; + + this->class = class; + this->stream = stream; + + this->pes_pkt = xine_xmalloc (1024*65); + this->spu_descriptor = xine_xmalloc(sizeof(spu_dvb_descriptor_t)); + + this->dvbsub = xine_xmalloc (sizeof (dvbsub_func_t)); + + for (i = 0; i < MAX_REGIONS; i++) { + this->dvbsub->page.regions[i].is_visible = 0; + this->dvbsub->regions[i].img = NULL; + this->dvbsub->regions[i].osd = NULL; + this->dvbsub->regions[i].CLUT_id = 0; + } + + { + xine_spu_opacity_t opacity; + static const clut_t black = { 0, 0, 0, 0 }; + int t; + + _x_spu_get_opacity (this->stream->xine, &opacity); + t = _x_spu_calculate_opacity (&black, 0, &opacity); + + for (i = 0; i < MAX_REGIONS * 256; i++) + this->dvbsub->colours[i].foo = t; + } + + pthread_mutex_init(&this->dvbsub_osd_mutex, NULL); + pthread_cond_init(&this->dvbsub_restart_timeout, NULL); + this->dvbsub_hide_timeout.tv_nsec = 0; + this->dvbsub_hide_timeout.tv_sec = time(NULL); + pthread_create(&this->dvbsub_timer_thread, NULL, dvbsub_timer_func, this); + + return (spu_decoder_t *) this; +} + +static void *init_spu_decoder_plugin (xine_t * xine, void *data) +{ + + dvb_spu_class_t *this; + this = (dvb_spu_class_t *) xine_xmalloc (sizeof (dvb_spu_class_t)); + + this->class.open_plugin = dvb_spu_class_open_plugin; + this->class.identifier = "spudvb"; + this->class.description = N_("DVB subtitle decoder plugin"); + this->class.dispose = default_spu_decoder_class_dispose; + + this->xine = xine; + + return &this->class; +} + + +/* plugin catalog information */ +static uint32_t supported_types[] = { BUF_SPU_DVB, 0 }; + +static const decoder_info_t spudec_info = { + supported_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { +/* type, API, "name", version, special_info, init_function */ + {PLUGIN_SPU_DECODER, 17, "spudvb", XINE_VERSION_CODE, &spudec_info, + &init_spu_decoder_plugin}, + {PLUGIN_NONE, 0, "", 0, NULL, NULL} +}; diff --git a/src/spu_dec/sputext_decoder.c b/src/spu_dec/sputext_decoder.c new file mode 100644 index 000000000..12d1986bb --- /dev/null +++ b/src/spu_dec/sputext_decoder.c @@ -0,0 +1,992 @@ +/* + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "libsputext" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include + +#define SUB_MAX_TEXT 5 /* lines */ +#define SUB_BUFSIZE 256 /* chars per line */ + +#define rgb2yuv(R,G,B) ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128)) + +static uint32_t sub_palette[22]={ +/* RED */ + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(50,10,10), + rgb2yuv(120,20,20), + rgb2yuv(185,50,50), + rgb2yuv(255,70,70), +/* BLUE */ + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,30,50), + rgb2yuv(0,90,120), + rgb2yuv(0,140,185), + rgb2yuv(0,170,255) +}; + +static uint8_t sub_trans[22]={ + 0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15, + 0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 +}; + +typedef enum { + SUBTITLE_SIZE_TINY = 0, + SUBTITLE_SIZE_SMALL, + SUBTITLE_SIZE_NORMAL, + SUBTITLE_SIZE_LARGE, + SUBTITLE_SIZE_VERY_LARGE, + SUBTITLE_SIZE_HUGE, + + SUBTITLE_SIZE_NUM /* number of values in enum */ +} subtitle_size; + +#define FONTNAME_SIZE 100 + +typedef struct sputext_class_s { + spu_decoder_class_t class; + + subtitle_size subtitle_size; /* size of subtitles */ + int vertical_offset; + char font[FONTNAME_SIZE]; /* subtitle font */ +#ifdef HAVE_FT2 + char font_ft[FILENAME_MAX]; /* subtitle font */ + int use_font_ft; /* use Freetype */ +#endif + char *src_encoding; /* encoding of subtitle file */ + int use_unscaled; /* use unscaled OSD if possible */ + + xine_t *xine; + +} sputext_class_t; + + +typedef struct sputext_decoder_s { + spu_decoder_t spu_decoder; + + sputext_class_t *class; + xine_stream_t *stream; + + int ogm; + int lines; + char text[SUB_MAX_TEXT][SUB_BUFSIZE]; + + /* below 3 variables are the same from class. use to detect + * when something changes. + */ + subtitle_size subtitle_size; /* size of subtitles */ + int vertical_offset; + char font[FILENAME_MAX]; /* subtitle font */ + char *buf_encoding; /* encoding of subtitle buffer */ + + int width; /* frame width */ + int height; /* frame height */ + int font_size; + int line_height; + int started; + int finished; + + osd_renderer_t *renderer; + osd_object_t *osd; + int current_osd_text; + uint32_t spu_palette[OVL_PALETTE_SIZE]; + uint8_t spu_trans[OVL_PALETTE_SIZE]; + + int64_t img_duration; + int64_t last_subtitle_end; /* no new subtitle before this vpts */ + int unscaled; /* use unscaled OSD */ + + int last_lines; /* number of lines of the previous subtitle */ +} sputext_decoder_t; + +static inline char *get_font (sputext_class_t *class) +{ +#ifdef HAVE_FT2 + return class->use_font_ft ? class->font_ft : class->font; +#else + return class->font; +#endif +} + +static void update_font_size (sputext_decoder_t *this, int force_update) { + static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 }; + + int y; + + if ((this->subtitle_size != this->class->subtitle_size) || + (this->vertical_offset != this->class->vertical_offset) || + force_update) { + + this->subtitle_size = this->class->subtitle_size; + this->vertical_offset = this->class->vertical_offset; + this->last_lines = 0; + + this->font_size = sizes[this->class->subtitle_size]; + + this->line_height = this->font_size + 10; + + y = this->height - (SUB_MAX_TEXT * this->line_height) - 5; + + if(((y - this->class->vertical_offset) >= 0) && ((y - this->class->vertical_offset) <= this->height)) + y -= this->class->vertical_offset; + + if( this->osd ) + this->renderer->free_object (this->osd); + + lprintf("new osd object, width %d, height %d*%d\n", this->width, SUB_MAX_TEXT, this->line_height); + this->osd = this->renderer->new_object (this->renderer, + this->width, + SUB_MAX_TEXT * this->line_height); + + this->renderer->set_font (this->osd, get_font (this->class), this->font_size); + this->renderer->set_position (this->osd, 0, y); + } +} + +static void update_output_size (sputext_decoder_t *this) { + int unscaled; + + unscaled = this->class->use_unscaled && + (this->stream->video_out->get_capabilities(this->stream->video_out) & + VO_CAP_UNSCALED_OVERLAY); + + if( unscaled != this->unscaled ) { + this->unscaled = unscaled; + this->width = 0; /* force update */ + } + + /* initialize decoder if needed */ + if( this->unscaled ) { + if( this->width != this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_WIDTH) || + this->height != this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_HEIGHT) || + !this->img_duration || !this->osd ) { + + int width = 0, height = 0; /* dummy */ + + this->stream->video_out->status(this->stream->video_out, NULL, + &width, &height, &this->img_duration ); + if( width && height ) { + + this->width = this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_WIDTH); + this->height = this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_HEIGHT); + + if(!this->osd || (this->width && this->height)) { + this->renderer = this->stream->osd_renderer; + + update_font_size (this, 1); + } + } + } + } else { + if( !this->width || !this->height || !this->img_duration || !this->osd ) { + + this->width = 0; + this->height = 0; + + this->stream->video_out->status(this->stream->video_out, NULL, + &this->width, &this->height, &this->img_duration ); + + if(!this->osd || ( this->width && this->height)) { + this->renderer = this->stream->osd_renderer; + + update_font_size (this, 1); + } + } + } +} + +static int parse_utf8_size(const void *buf) +{ + const uint8_t *c = buf; + if ( c[0]<0x80 ) + return 1; + + if( c[1]==0 ) + return 1; + if ( (c[0]>=0xC2 && c[0]<=0xDF) && (c[1]>=0x80 && c[1]<=0xBF) ) + return 2; + + if( c[2]==0 ) + return 2; + else if ( c[0]==0xE0 && (c[1]>=0xA0 && c[1]<=0xBF) && (c[2]>=0x80 && c[1]<=0xBF) ) + return 3; + else if ( (c[0]>=0xE1 && c[0]<=0xEC) && (c[1]>=0x80 && c[1]<=0xBF) && (c[2]>=0x80 && c[1]<=0xBF) ) + return 3; + else if ( c[0]==0xED && (c[1]>=0x80 && c[1]<=0x9F) && (c[2]>=0x80 && c[1]<=0xBF) ) + return 3; + else if ( c[0]==0xEF && (c[1]>=0xA4 && c[1]<=0xBF) && (c[2]>=0x80 && c[1]<=0xBF) ) + return 3; + else + return 1; +} + +static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const char *text, int render) +{ + int i = 0, w, dummy; + char letter[5]={0, 0, 0, 0, 0}; + const char *encoding = this->buf_encoding ? this->buf_encoding + : this->class->src_encoding; + int shift, isutf8 = !strcmp(encoding, "utf-8"); + size_t length = strlen (text); + + while (i <= length) { + switch (text[i]) { + case '<': + if (!strncmp("", text+i, 3)) { + /* enable Bold color */ + if (render) + this->current_osd_text = OSD_TEXT2; + i=i+3; + break; + } else if (!strncmp("", text+i, 4)) { + /* disable BOLD */ + if (render) + this->current_osd_text = OSD_TEXT1; + i=i+4; + break; + } else if (!strncmp("", text+i, 3)) { + /* enable italics color */ + if (render) + this->current_osd_text = OSD_TEXT3; + i=i+3; + break; + } else if (!strncmp("", text+i, 4)) { + /* disable italics */ + if (render) + this->current_osd_text = OSD_TEXT1; + i=i+4; + break; + } else if (!strncmp("", text+i, 6)) { + /*Do somethink to disable typing + fixme - no teststreams*/ + i=i+6; + break; + } else if (!strncmp("", text+i, 7)) { + /*Do somethink to enable typing + fixme - no teststreams*/ + i=i+7; + break; + } + default: + shift = isutf8 ? parse_utf8_size (&text[i]) : 1; + memcpy(letter,&text[i],shift); + letter[shift]=0; + + if (render) + this->renderer->render_text(this->osd, x, y, letter, this->current_osd_text); + this->renderer->get_text_size(this->osd, letter, &w, &dummy); + x=x+w; + i+=shift; + } + } + return x; +} + +static inline int ogm_get_width(sputext_decoder_t *this, char* text) { + return ogm_render_line_internal (this, 0, 0, text, 0); +} + +static inline void ogm_render_line(sputext_decoder_t *this, int x, int y, char* text) { + ogm_render_line_internal (this, x, y, text, 1); +} + +static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t sub_end ) { + + int line, y; + int font_size; + char *font; + + _x_assert(this->renderer != NULL); + if ( ! this->renderer ) + return; + + update_font_size(this, 0); + + font = get_font (this->class); + if( strcmp(this->font, font) ) { + strncpy(this->font, font, FILENAME_MAX); + this->font[FILENAME_MAX - 1] = '\0'; + this->renderer->set_font (this->osd, font, this->font_size); + } + + font_size = this->font_size; + if (this->buf_encoding) + this->renderer->set_encoding(this->osd, this->buf_encoding); + else + this->renderer->set_encoding(this->osd, this->class->src_encoding); + + for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */ + { + int w; + w = ogm_get_width( this, this->text[line]); + if( w > this->width ) { /* line is too long */ + int chunks=(int)(w/this->width)+(w%this->width?1:0); + if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */ + int a; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,"Partial subtitle line splitting in %i chunks\n",chunks); + for(a=this->lines-1;a>=0;a--) { + if(a>line) /* lines after the too-long one */ + memcpy(this->text[a+chunks-1],this->text[a],SUB_BUFSIZE); + else if(a==line) { /* line to be splitted */ + int b,len=strlen(this->text[line]); + char *p=this->text[line]; + for(b=0;btext[line+b],p,SUB_BUFSIZE); + this->text[line+b][SUB_BUFSIZE - 1] = '\0'; + } else { + for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--); + if(*c==' ') { + *c='\0'; + if(b) { /* we are reading something that has to be moved to another line */ + strncpy(this->text[line+b],p,SUB_BUFSIZE); + this->text[line+b][SUB_BUFSIZE - 1] = '\0'; + } + p=c+1; + } + } + } + } + } + this->lines+=chunks-1; + } else { /* regenerate all the lines to find something that better fits */ + char buf[SUB_BUFSIZE*SUB_MAX_TEXT]; + int a,w,chunks; + buf[0]='\0'; + for(a=0;alines;a++) { + if(a) { + int len=strlen(buf); + buf[len]=' '; + buf[len+1]='\0'; + } + strcat(buf,this->text[a]); + } + w = ogm_get_width( this, buf); + chunks=(int)(w/this->width)+(w%this->width?1:0); + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks); + if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */ + int b,len=strlen(buf); + char *p=buf; + for(b=0;btext[b],p,SUB_BUFSIZE); + this->text[b][SUB_BUFSIZE - 1] = '\0'; + } else { + for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--); + if(*c==' ') { + *c='\0'; + strncpy(this->text[b],p,SUB_BUFSIZE); + this->text[b][SUB_BUFSIZE - 1] = '\0'; + p=c+1; + } + } + } + this->lines=chunks; + } else + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Subtitle too long to be splited\n"); + line=this->lines; + } + } + } + + font_size = this->font_size; + if (this->buf_encoding) + this->renderer->set_encoding(this->osd, this->buf_encoding); + else + this->renderer->set_encoding(this->osd, this->class->src_encoding); + + for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */ + { + int w; + w = ogm_get_width( this, this->text[line]); + if( w > this->width ) { /* line is too long */ + int chunks=(int)(w/this->width)+(w%this->width?1:0); + if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */ + int a; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,"Partial subtitle line splitting in %i chunks\n",chunks); + for(a=this->lines-1;a>=0;a--) { + if(a>line) /* lines after the too-long one */ + memcpy(this->text[a+chunks-1],this->text[a],SUB_BUFSIZE); + else if(a==line) { /* line to be splitted */ + int b,len=strlen(this->text[line]); + char *p=this->text[line]; + for(b=0;btext[line+b],p,SUB_BUFSIZE); + this->text[line+b][SUB_BUFSIZE - 1] = '\0'; + } else { + for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--); + if(*c==' ') { + *c='\0'; + if(b) { /* we are reading something that has to be moved to another line */ + strncpy(this->text[line+b],p,SUB_BUFSIZE); + this->text[line+b][SUB_BUFSIZE - 1] = '\0'; + } + p=c+1; + } + } + } + } + } + this->lines+=chunks-1; + } else { /* regenerate all the lines to find something that better fits */ + char buf[SUB_BUFSIZE*SUB_MAX_TEXT]; + int a,w,chunks; + buf[0]='\0'; + for(a=0;alines;a++) { + if(a) { + int len=strlen(buf); + buf[len]=' '; + buf[len+1]='\0'; + } + strcat(buf,this->text[a]); + } + w = ogm_get_width( this, buf); + chunks=(int)(w/this->width)+(w%this->width?1:0); + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks); + if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */ + int b,len=strlen(buf); + char *p=buf; + for(b=0;btext[b],p,SUB_BUFSIZE); + this->text[b][SUB_BUFSIZE - 1] = '\0'; + } else { + for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--); + if(*c==' ') { + *c='\0'; + strncpy(this->text[b],p,SUB_BUFSIZE); + this->text[b][SUB_BUFSIZE - 1] = '\0'; + p=c+1; + } + } + } + this->lines=chunks; + } else + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Subtitle too long to be splited\n"); + line=this->lines; + } + } + } + + if (this->last_lines) + this->renderer->filled_rect (this->osd, 0, this->line_height * (SUB_MAX_TEXT - this->last_lines), + this->width - 1, this->line_height * SUB_MAX_TEXT - 1, 0); + this->last_lines = this->lines; + y = (SUB_MAX_TEXT - this->lines) * this->line_height; + + for (line = 0; line < this->lines; line++) { + int w, x; + + while(1) { + w = ogm_get_width( this, this->text[line]); + x = (this->width - w) / 2; + + if( w > this->width && font_size > 16 ) { + font_size -= 4; + this->renderer->set_font (this->osd, get_font (this->class), font_size); + } else { + break; + } + } + + ogm_render_line(this, x, y + line*this->line_height, this->text[line]); + } + + if( font_size != this->font_size ) + this->renderer->set_font (this->osd, get_font (this->class), this->font_size); + + if( this->last_subtitle_end && sub_start < this->last_subtitle_end ) { + sub_start = this->last_subtitle_end; + } + this->last_subtitle_end = sub_end; + + this->renderer->set_text_palette (this->osd, -1, OSD_TEXT1); + this->renderer->get_palette(this->osd, this->spu_palette, this->spu_trans); + /* append some colors for colored typeface tag */ + memcpy(this->spu_palette+OSD_TEXT2, sub_palette, sizeof(sub_palette)); + memcpy(this->spu_trans+OSD_TEXT2, sub_trans, sizeof(sub_trans)); + this->renderer->set_palette(this->osd, this->spu_palette, this->spu_trans); + + if (this->unscaled) + this->renderer->show_unscaled (this->osd, sub_start); + else + this->renderer->show (this->osd, sub_start); + + this->renderer->hide (this->osd, sub_end); + + lprintf ("scheduling subtitle >%s< at %"PRId64" until %"PRId64", current time is %"PRId64"\n", + this->text[0], sub_start, sub_end, + this->stream->xine->clock->get_current_time (this->stream->xine->clock)); +} + + +static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { + + sputext_decoder_t *this = (sputext_decoder_t *) this_gen; + int uses_time; + int32_t start, end, diff; + int64_t start_vpts, end_vpts; + int64_t spu_offset; + int i; + uint32_t *val; + char *str; + extra_info_t extra_info; + int master_status, slave_status; + int vo_discard; + + /* filter unwanted streams */ + if (buf->decoder_flags & BUF_FLAG_HEADER) { + return; + } + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if ((this->stream->spu_channel & 0x1f) != (buf->type & 0x1f)) + return; + + if ( (buf->decoder_flags & BUF_FLAG_SPECIAL) && + (buf->decoder_info[1] == BUF_SPECIAL_CHARSET_ENCODING) ) + this->buf_encoding = buf->decoder_info_ptr[2]; + else + this->buf_encoding = NULL; + + this->current_osd_text = OSD_TEXT1; + + if( (buf->type & 0xFFFF0000) == BUF_SPU_OGM ) { + + this->ogm = 1; + uses_time = 1; + val = (uint32_t * )buf->content; + start = *val++; + end = *val++; + str = (char *)val; + + if (!*str) return; + /* Empty ogm packets (as created by ogmmux) clears out old messages. We already respect the end time. */ + + this->lines = 0; + + i = 0; + while (*str && (this->lines < SUB_MAX_TEXT) && (i < SUB_BUFSIZE)) { + if (*str == '\r' || *str == '\n') { + if (i) { + this->text[ this->lines ][i] = 0; + this->lines++; + i = 0; + } + } else { + this->text[ this->lines ][i] = *str; + if (i < SUB_BUFSIZE-1) + i++; + } + str++; + } + if (i == SUB_BUFSIZE) + i--; + + if (i) { + this->text[ this->lines ][i] = 0; + this->lines++; + } + + } else { + + this->ogm = 0; + val = (uint32_t * )buf->content; + + this->lines = *val++; + uses_time = *val++; + start = *val++; + end = *val++; + str = (char *)val; + for (i = 0; i < this->lines; i++, str += strlen(str) + 1) { + strncpy( this->text[i], str, SUB_BUFSIZE - 1); + this->text[i][SUB_BUFSIZE - 1] = '\0'; + } + + } + + xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, + "libsputext: decoder data [%s]\n", this->text[0]); + xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, + "libsputext: mode %d timing %d->%d\n", uses_time, start, end); + + if( end <= start ) { + xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, + "libsputext: discarding subtitle with invalid timing\n"); + return; + } + + spu_offset = this->stream->master->metronom->get_option (this->stream->master->metronom, + METRONOM_SPU_OFFSET); + if( uses_time ) { + start += (spu_offset / 90); + end += (spu_offset / 90); + } else { + if( this->osd && this->img_duration ) { + start += spu_offset / this->img_duration; + end += spu_offset / this->img_duration; + } + } + + while( !this->finished ) { + + master_status = xine_get_status (this->stream->master); + slave_status = xine_get_status (this->stream); + vo_discard = this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_DISCARD_FRAMES); + + _x_get_current_info (this->stream->master, &extra_info, sizeof(extra_info) ); + + lprintf("master: %d slave: %d input_normpos: %d vo_discard: %d\n", + master_status, slave_status, extra_info.input_normpos, vo_discard); + + if( !this->started && (master_status == XINE_STATUS_PLAY && + slave_status == XINE_STATUS_PLAY && + extra_info.input_normpos) ) { + lprintf("started\n"); + + this->width = this->height = 0; + + update_output_size( this ); + if( this->width && this->height ) { + this->started = 1; + } + } + + if( this->started ) { + + if( master_status != XINE_STATUS_PLAY || + slave_status != XINE_STATUS_PLAY || + vo_discard ) { + lprintf("finished\n"); + + this->width = this->height = 0; + this->finished = 1; + return; + } + + if( this->osd ) { + + /* try to use frame number mode */ + if( !uses_time && extra_info.frame_number ) { + + diff = end - extra_info.frame_number; + + /* discard old subtitles */ + if( diff < 0 ) { + xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, + "libsputext: discarding old subtitle\n"); + return; + } + + diff = start - extra_info.frame_number; + + start_vpts = extra_info.vpts + diff * this->img_duration; + end_vpts = start_vpts + (end-start) * this->img_duration; + + } else { + + if( !uses_time ) { + start = start * this->img_duration / 90; + end = end * this->img_duration / 90; + uses_time = 1; + } + + diff = end - extra_info.input_time; + + /* discard old subtitles */ + if( diff < 0 ) { + xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, + "libsputext: discarding old subtitle\n"); + return; + } + + diff = start - extra_info.input_time; + + start_vpts = extra_info.vpts + diff * 90; + end_vpts = start_vpts + (end-start) * 90; + } + + _x_spu_decoder_sleep(this->stream, start_vpts); + update_output_size( this ); + draw_subtitle(this, start_vpts, end_vpts); + + return; + } + } + + if (_x_spu_decoder_sleep(this->stream, 0)) + xine_usec_sleep (50000); + else + return; + } +} + + +static void spudec_reset (spu_decoder_t *this_gen) { + sputext_decoder_t *this = (sputext_decoder_t *) this_gen; + + lprintf("i guess we just seeked\n"); + this->width = this->height = 0; + this->started = this->finished = 0; + this->last_subtitle_end = 0; +} + +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) { + this->renderer->free_object (this->osd); + this->osd = NULL; + } + free(this); +} + +static void update_vertical_offset(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->vertical_offset = entry->num_value; +} + +static void update_osd_font(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + strncpy(class->font, entry->str_value, FONTNAME_SIZE); + class->font[FONTNAME_SIZE - 1] = '\0'; + + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_font = %s\n", class->font ); +} + +#ifdef HAVE_FT2 +static void update_osd_font_ft(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + strncpy(class->font_ft, entry->str_value, FILENAME_MAX); + class->font_ft[FILENAME_MAX - 1] = '\0'; + + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_font_ft = %s\n", class->font_ft); +} + +static void update_osd_use_font_ft(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->use_font_ft = entry->num_value; + + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_use_font_ft = %d\n", class->use_font_ft); +} +#endif + +static void update_subtitle_size(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->subtitle_size = entry->num_value; +} + +static void update_use_unscaled(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->use_unscaled = entry->num_value; +} + +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 ; + + this = (sputext_decoder_t *) xine_xmalloc (sizeof (sputext_decoder_t)); + + this->spu_decoder.decode_data = spudec_decode_data; + this->spu_decoder.reset = spudec_reset; + this->spu_decoder.discontinuity = spudec_discontinuity; + this->spu_decoder.get_interact_info = NULL; + this->spu_decoder.set_button = NULL; + this->spu_decoder.dispose = spudec_dispose; + + this->class = class; + this->stream = stream; + + return (spu_decoder_t *) this; +} + +static void sputext_class_dispose (spu_decoder_class_t *class_gen) { + sputext_class_t *this = (sputext_class_t *)class_gen; + + this->xine->config->unregister_callback(this->xine->config, + "subtitles.separate.src_encoding"); + this->xine->config->unregister_callback(this->xine->config, + "subtitles.separate.subtitle_size"); + this->xine->config->unregister_callback(this->xine->config, + "subtitles.separate.vertical_offset"); + this->xine->config->unregister_callback(this->xine->config, + "subtitles.separate.use_unscaled_osd"); + free (this); +} + +static void update_src_encoding(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->src_encoding = entry->str_value; + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_src_encoding = %s\n", class->src_encoding ); +} + +static void *init_spu_decoder_plugin (xine_t *xine, void *data) { + + static const char *const subtitle_size_strings[] = { + "tiny", "small", "normal", "large", "very large", "huge", NULL + }; + sputext_class_t *this ; + + lprintf("init class\n"); + + this = (sputext_class_t *) xine_xmalloc (sizeof (sputext_class_t)); + + this->class.open_plugin = sputext_class_open_plugin; + this->class.identifier = "sputext"; + this->class.description = N_("external subtitle decoder plugin"); + this->class.dispose = sputext_class_dispose; + + this->xine = xine; + + this->subtitle_size = xine->config->register_enum(xine->config, + "subtitles.separate.subtitle_size", + 1, + subtitle_size_strings, + _("subtitle size"), + _("You can adjust the subtitle size here. The setting will " + "be evaluated relative to the window size."), + 0, update_subtitle_size, this); + this->vertical_offset = xine->config->register_num(xine->config, + "subtitles.separate.vertical_offset", + 0, + _("subtitle vertical offset"), + _("You can adjust the vertical position of the subtitle. " + "The setting will be evaluated relative to the window size."), + 0, update_vertical_offset, this); + strncpy(this->font, xine->config->register_string(xine->config, + "subtitles.separate.font", + "sans", + _("font for subtitles"), + _("A font from the xine font directory to be used for the " + "subtitle text."), + 10, update_osd_font, this), FONTNAME_SIZE); + this->font[FONTNAME_SIZE - 1] = '\0'; +#ifdef HAVE_FT2 + strncpy(this->font_ft, xine->config->register_filename(xine->config, + "subtitles.separate.font_freetype", + "", XINE_CONFIG_STRING_IS_FILENAME, + _("font for subtitles"), + _("An outline font file (e.g. a .ttf) to be used for the subtitle text."), + 10, update_osd_font_ft, this), FILENAME_MAX); + this->font_ft[FILENAME_MAX - 1] = '\0'; + this->use_font_ft = xine->config->register_bool(xine->config, + "subtitles.separate.font_use_freetype", + 0, + _("whether to use a freetype font"), + NULL, + 10, update_osd_use_font_ft, this); +#endif + this->src_encoding = xine->config->register_string(xine->config, + "subtitles.separate.src_encoding", + xine_guess_spu_encoding(), + _("encoding of the subtitles"), + _("The encoding of the subtitle text in the stream. This setting " + "is used to render non-ASCII characters correctly. If non-ASCII " + "characters are not displayed as you expect, ask the " + "creator of the subtitles what encoding was used."), + 10, update_src_encoding, this); + this->use_unscaled = xine->config->register_bool(xine->config, + "subtitles.separate.use_unscaled_osd", + 1, + _("use unscaled OSD if possible"), + _("The unscaled OSD will be rendered independently of the video " + "frame and will always be sharp, even if the video is magnified. " + "This will look better, but does not work with all graphics " + "hardware. The alternative is the scaled OSD, which will become " + "blurry, if you enlarge a low resolution video to fullscreen, but " + "it works with all graphics cards."), + 10, update_use_unscaled, this); + + return &this->class; +} + + +/* plugin catalog information */ +static uint32_t supported_types[] = { BUF_SPU_TEXT, BUF_SPU_OGM, 0 }; + +static const decoder_info_t spudec_info = { + supported_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_SPU_DECODER | PLUGIN_MUST_PRELOAD, 17, "sputext", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/spu_dec/sputext_demuxer.c b/src/spu_dec/sputext_demuxer.c new file mode 100644 index 000000000..270894f50 --- /dev/null +++ b/src/spu_dec/sputext_demuxer.c @@ -0,0 +1,1489 @@ +/* + * Copyright (C) 2000-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * code based on old libsputext/xine_decoder.c + * + * code based on mplayer module: + * + * Subtitle reader with format autodetection + * + * Written by laaz + * Some code cleanup & realloc() by A'rpi/ESP-team + * dunnowhat sub format by szabi + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "demux_sputext" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include + +#define ERR (void *)-1 +#define SUB_MAX_TEXT 5 +#define SUB_BUFSIZE 1024 +#define LINE_LEN 1000 +#define LINE_LEN_QUOT "1000" + +/* + * Demuxer typedefs + */ + +typedef struct { + + int lines; + + long start; /* csecs */ + long end; /* csecs */ + + char *text[SUB_MAX_TEXT]; + +} subtitle_t; + + +typedef struct { + + demux_plugin_t demux_plugin; + xine_stream_t *stream; + input_plugin_t *input; + + int status; + + char buf[SUB_BUFSIZE]; + off_t buflen; + + float mpsub_position; + + int uses_time; + int errs; + subtitle_t *subtitles; + int num; /* number of subtitle structs */ + int cur; /* current subtitle */ + int format; /* constants see below */ + char next_line[SUB_BUFSIZE]; /* a buffer for next line read from file */ + +} demux_sputext_t; + +typedef struct demux_sputext_class_s { + + demux_class_t demux_class; + + int max_timeout; /* default timeout of hidding subtitles */ + +} demux_sputext_class_t; + +/* + * Demuxer code start + */ + +#define FORMAT_UNKNOWN -1 +#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_PJS 7 +#define FORMAT_MPSUB 8 +#define FORMAT_AQTITLE 9 +#define FORMAT_JACOBSUB 10 +#define FORMAT_SUBVIEWER2 11 +#define FORMAT_SUBRIP09 12 +#define FORMAT_MPL2 13 /*Mplayer sub 2 ?*/ + +static int eol(char p) { + return (p=='\r' || p=='\n' || p=='\0'); +} + +static inline void trail_space(char *s) { + int i; + while (isspace(*s)) { + char *copy = s; + do { + copy[0] = copy[1]; + copy++; + } while(*copy); + } + i = strlen(s) - 1; + while (i > 0 && isspace(s[i])) + s[i--] = '\0'; +} + +/* + * Reimplementation of fgets() using the input->read() method. + */ +static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len) { + off_t nread = 0; + char *s; + int linelen; + + if ((len - this->buflen) > 512) { + if((nread = this->input->read(this->input, + &this->buf[this->buflen], len - this->buflen)) < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "read failed.\n"); + return NULL; + } + } + + this->buflen += nread; + this->buf[this->buflen] = '\0'; + + s = strchr(this->buf, '\n'); + + if (line && (s || this->buflen)) { + + linelen = s ? (s - this->buf) + 1 : this->buflen; + + memcpy(line, this->buf, linelen); + line[linelen] = '\0'; + + memmove(this->buf, &this->buf[linelen], SUB_BUFSIZE - linelen); + this->buflen -= linelen; + + return line; + } + + return NULL; +} + + +static subtitle_t *sub_read_line_sami(demux_sputext_t *this, subtitle_t *current) { + + static char line[LINE_LEN + 1]; + static char *s = NULL; + char text[LINE_LEN + 1], *p, *q; + int state; + + p = NULL; + current->lines = current->start = 0; + current->end = -1; + state = 0; + + /* read the first line */ + if (!s) + if (!(s = read_line_from_input(this, line, LINE_LEN))) 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 "" */ + 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, "
", 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 */ + 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 = read_line_from_input (this, line, LINE_LEN))) + 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(demux_sputext_t *this, subtitle_t *current) { + + char line[LINE_LEN + 1]; + char line2[LINE_LEN + 1]; + char *p, *next; + int i; + + memset (current, 0, sizeof(subtitle_t)); + + current->end=-1; + do { + if (!read_line_from_input (this, line, LINE_LEN)) return NULL; + } while ((sscanf (line, "{%ld}{}%" LINE_LEN_QUOT "[^\r\n]", &(current->start), line2) !=2) && + (sscanf (line, "{%ld}{%ld}%" LINE_LEN_QUOT "[^\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) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); + current->lines=i; + return current; + } + } + current->lines= ++i; + + return current; +} + +static subtitle_t *sub_read_line_subviewer(demux_sputext_t *this, subtitle_t *current) { + + char line[LINE_LEN + 1]; + int a1,a2,a3,a4,b1,b2,b3,b4; + char *p=NULL, *q=NULL; + int len; + + memset (current, 0, sizeof(subtitle_t)); + + while (1) { + if (!read_line_from_input(this, line, LINE_LEN)) return NULL; + if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) { + 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 (!read_line_from_input(this, line, LINE_LEN)) + 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' && *p!='|' && strncasecmp(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; + if (*p=='[') while (*p++!=']'); + if (*p=='|') p++; + } + if (current->lines > SUB_MAX_TEXT) current->lines = SUB_MAX_TEXT; + break; + } + return current; +} + +static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *current) { + char line[LINE_LEN + 1]; + int a1,a2,a3,a4,b1,b2,b3,b4; + int i,end_sub; + + memset(current,0,sizeof(subtitle_t)); + do { + if(!read_line_from_input(this,line,LINE_LEN)) + return NULL; + i = sscanf(line,"%d:%d:%d%*[,.]%d --> %d:%d:%d%*[,.]%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4); + } while(i < 8); + current->start = a1*360000+a2*6000+a3*100+a4/10; + current->end = b1*360000+b2*6000+b3*100+b4/10; + i=0; + end_sub=0; + do { + char *p; /* pointer to the curently read char */ + char temp_line[SUB_BUFSIZE]; /* subtitle line that will be transfered to current->text[i] */ + int temp_index; /* ... and its index wich 'points' to the first EMPTY place -> last read char is at temp_index-1 if temp_index>0 */ + temp_line[SUB_BUFSIZE-1]='\0'; /* just in case... */ + if(!read_line_from_input(this,line,LINE_LEN)) { + if(i) + break; /* if something was read, transmit it */ + else + return NULL; /* if not, repport EOF */ + } + for(temp_index=0,p=line;*p!='\0' && !end_sub && temp_index0) { + if(temp_index==SUB_BUFSIZE) + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many characters in a subtitle line\n"); + if(temp_line[temp_index-1]=='\0' || temp_index==SUB_BUFSIZE) { + if(temp_index>1) { /* more than 1 char (including '\0') -> that is a valid one */ + current->text[i]=(char *)xine_xmalloc(temp_index); + if(!current->text[i]) + return ERR; + strncpy(current->text[i],temp_line,temp_index); /* temp_index<=SUB_BUFSIZE is always true here */ + i++; + temp_index=0; + } else + end_sub=1; + } + } + } + } while(i=SUB_MAX_TEXT) + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); + current->lines=i; + return current; +} + +static subtitle_t *sub_read_line_vplayer(demux_sputext_t *this,subtitle_t *current) { + char line[LINE_LEN + 1]; + int a1,a2,a3,b1,b2,b3; + char *p=NULL, *next, *p2; + int i; + + memset (current, 0, sizeof(subtitle_t)); + + while (!current->text[0]) { + if( this->next_line[0] == '\0' ) { /* if the buffer is empty.... */ + if( !read_line_from_input(this, line, LINE_LEN) ) return NULL; + } else { + /* ... get the current line from buffer. */ + strncpy( line, this->next_line, LINE_LEN); + line[LINE_LEN] = '\0'; /* I'm scared. This makes me feel better. */ + this->next_line[0] = '\0'; /* mark the buffer as empty. */ + } + /* Initialize buffer with next line */ + if( ! read_line_from_input( this, this->next_line, LINE_LEN) ) { + this->next_line[0] = '\0'; + return NULL; + } + if( (sscanf( line, "%d:%d:%d:", &a1, &a2, &a3) < 3) || + (sscanf( this->next_line, "%d:%d:%d:", &b1, &b2, &b3) < 3) ) + continue; + current->start = a1*360000+a2*6000+a3*100; + current->end = b1*360000+b2*6000+b3*100; + if ((current->end - current->start) > LINE_LEN) + current->end = current->start + LINE_LEN; /* not too long though. */ + /* teraz czas na wkopiowanie stringu */ + p=line; + /* finds the body of the subtitle_t */ + for (i=0; i<3; i++){ + p2=strchr( p, ':'); + if( p2 == NULL ) break; + p=p2+1; + } + + 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) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); + current->lines=i; + return current; + } + } + current->lines=++i; + } + return current; +} + +static subtitle_t *sub_read_line_rt(demux_sputext_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[LINE_LEN + 1]; + int a1,a2,a3,a4,b1,b2,b3,b4; + char *p=NULL,*next=NULL; + int i,len,plen; + + memset (current, 0, sizeof(subtitle_t)); + + while (!current->text[0]) { + if (!read_line_from_input(this, line, LINE_LEN)) 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, "