summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-10-06 21:52:42 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-10-06 21:52:42 +0000
commit2e29bd1fe0c87addc57755fb9812569e75cd4e39 (patch)
treeef23e232f9d63823f44bb6c4ffd604989cc222a0 /src
parentc3a7991dd5e1b7a1013afd4e2c154fc870553c1c (diff)
downloadxine-lib-2e29bd1fe0c87addc57755fb9812569e75cd4e39.tar.gz
xine-lib-2e29bd1fe0c87addc57755fb9812569e75cd4e39.tar.bz2
- add XvMC support
- bump vo and post interface versions obs: video_out_xvmc.c needs some more work, see todo. CVS patchset: 5459 CVS date: 2003/10/06 21:52:42
Diffstat (limited to 'src')
-rw-r--r--src/dxr3/video_out_dxr3.c6
-rw-r--r--src/libmpeg2/Makefile.am3
-rw-r--r--src/libmpeg2/decode.c58
-rw-r--r--src/libmpeg2/idct.c33
-rw-r--r--src/libmpeg2/idct_mlib.c5
-rw-r--r--src/libmpeg2/idct_mmx.c14
-rw-r--r--src/libmpeg2/mpeg2.h7
-rw-r--r--src/libmpeg2/mpeg2_internal.h43
-rw-r--r--src/libmpeg2/slice_xvmc.c2066
-rw-r--r--src/libmpeg2/xine_decoder.c4
-rw-r--r--src/post/deinterlace/xine_plugin.c4
-rw-r--r--src/post/goom/xine_goom.c4
-rw-r--r--src/post/mosaico/mosaico.c4
-rw-r--r--src/post/mosaico/switch.c4
-rw-r--r--src/post/planar/boxblur.c13
-rw-r--r--src/post/planar/denoise3d.c14
-rw-r--r--src/post/planar/eq.c12
-rw-r--r--src/post/planar/eq2.c13
-rw-r--r--src/post/planar/expand.c11
-rw-r--r--src/post/planar/invert.c15
-rw-r--r--src/post/planar/planar.c16
-rw-r--r--src/post/planar/unsharp.c13
-rw-r--r--src/post/visualizations/fooviz.c4
-rw-r--r--src/post/visualizations/visualizations.c8
-rw-r--r--src/video_out/Makefile.am15
-rw-r--r--src/video_out/video_out_aa.c4
-rw-r--r--src/video_out/video_out_directfb.c4
-rwxr-xr-xsrc/video_out/video_out_directx.c2
-rw-r--r--src/video_out/video_out_fb.c4
-rw-r--r--src/video_out/video_out_none.c4
-rw-r--r--src/video_out/video_out_opengl.c4
-rw-r--r--src/video_out/video_out_pgx64.c4
-rw-r--r--src/video_out/video_out_sdl.c4
-rw-r--r--src/video_out/video_out_stk.c4
-rw-r--r--src/video_out/video_out_syncfb.c4
-rw-r--r--src/video_out/video_out_vidix.c6
-rw-r--r--src/video_out/video_out_xshm.c4
-rw-r--r--src/video_out/video_out_xv.c4
-rw-r--r--src/video_out/video_out_xvmc.c1908
-rw-r--r--src/xine-engine/post.c33
-rw-r--r--src/xine-engine/post.h4
-rw-r--r--src/xine-engine/video_out.c3
-rw-r--r--src/xine-engine/video_out.h72
43 files changed, 4288 insertions, 173 deletions
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
index 2c378ad25..51e872af7 100644
--- a/src/dxr3/video_out_dxr3.c
+++ b/src/dxr3/video_out_dxr3.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_dxr3.c,v 1.87 2003/09/13 15:29:33 miguelfreitas Exp $
+ * $Id: video_out_dxr3.c,v 1.88 2003/10/06 21:52:43 miguelfreitas Exp $
*/
/* mpeg1 encoding video out plugin for the dxr3.
@@ -91,9 +91,9 @@ static vo_info_t vo_info_dxr3_aa = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
#ifdef HAVE_X11
- { PLUGIN_VIDEO_OUT, 16, "dxr3", XINE_VERSION_CODE, &vo_info_dxr3_x11, &dxr3_x11_init_plugin },
+ { PLUGIN_VIDEO_OUT, 17, "dxr3", XINE_VERSION_CODE, &vo_info_dxr3_x11, &dxr3_x11_init_plugin },
#endif
- { PLUGIN_VIDEO_OUT, 16, "aadxr3", XINE_VERSION_CODE, &vo_info_dxr3_aa, &dxr3_aa_init_plugin },
+ { PLUGIN_VIDEO_OUT, 17, "aadxr3", XINE_VERSION_CODE, &vo_info_dxr3_aa, &dxr3_aa_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am
index d84b43780..7e5dbeb15 100644
--- a/src/libmpeg2/Makefile.am
+++ b/src/libmpeg2/Makefile.am
@@ -21,10 +21,11 @@ xineplug_decode_mpeg2_la_SOURCES = \
motion_comp_mmx.c \
motion_comp_mlib.c \
slice.c \
+ slice_xvmc.c \
stats.c \
xine_decoder.c
xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB)
xineplug_decode_mpeg2_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
-noinst_HEADERS = vlc.h mpeg2.h mpeg2_internal.h
+noinst_HEADERS = vlc.h mpeg2.h mpeg2_internal.h
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 0f9742fe4..a55c069a8 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -50,7 +50,8 @@
static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer);
-void mpeg2_init (mpeg2dec_t * mpeg2dec)
+void mpeg2_init (mpeg2dec_t * mpeg2dec,
+ xine_video_port_t * output)
{
static int do_init = 1;
uint32_t mm_accel;
@@ -71,11 +72,13 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec)
(void**)&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;
@@ -84,6 +87,13 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec)
/* initialize substructures */
mpeg2_header_state_init (mpeg2dec->picture);
+
+ 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)
@@ -400,6 +410,11 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
break;
}
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->frame_width != picture->coded_picture_width)
|| (picture->frame_height != picture->coded_picture_height)) {
@@ -465,7 +480,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
if (!(mpeg2dec->in_slice)) {
mpeg2dec->in_slice = 1;
-
+
if (picture->second_field) {
if (picture->current_frame)
picture->current_frame->field(picture->current_frame,
@@ -475,6 +490,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
} else {
int flags = VO_INTERLACED_FLAG | picture->picture_structure;
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 &&
@@ -487,7 +503,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->coded_picture_width,
picture->coded_picture_height,
get_aspect_ratio(mpeg2dec),
- XINE_IMGFMT_YV12,
+ mpeg2dec->frame_format,
flags);
else {
picture->current_frame =
@@ -495,7 +511,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->coded_picture_width,
picture->coded_picture_height,
get_aspect_ratio(mpeg2dec),
- XINE_IMGFMT_YV12,
+ mpeg2dec->frame_format,
flags);
if (picture->forward_reference_frame &&
picture->forward_reference_frame != picture->backward_reference_frame)
@@ -505,6 +521,11 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->backward_reference_frame;
picture->backward_reference_frame = picture->current_frame;
}
+ if(mpeg2dec->new_sequence)
+ {
+ picture->mc = picture->current_frame->macroblocks;
+ mpeg2dec->new_sequence = 0;
+ }
picture->current_frame->bad_frame = 1;
picture->current_frame->drawn = 0;
picture->current_frame->pts = mpeg2dec->pts;
@@ -512,6 +533,21 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->current_frame->repeat_first_field = picture->repeat_first_field;
picture->current_frame->progressive_frame = picture->progressive_frame;
+ 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;
+ }
+
#ifdef LOG
printf ("libmpeg2: decoding frame %d, type %s\n",
picture->current_frame->id, picture->picture_coding_type == I_TYPE ? "I" :
@@ -522,7 +558,17 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
}
if (!mpeg2dec->drop_frame && picture->current_frame != NULL) {
- mpeg2_slice (picture, code, buffer);
+#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
+
+ if(picture->mc && picture->mc->xvmc_accel) {
+ mpeg2_xvmc_slice (picture, code, buffer);
+
+ } else {
+ mpeg2_slice (picture, code, buffer);
+ }
if( picture->v_offset > picture->limit_y ) {
picture->current_frame->bad_frame = 0;
@@ -796,6 +842,8 @@ void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec,
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;
diff --git a/src/libmpeg2/idct.c b/src/libmpeg2/idct.c
index 645fc03c1..d2b3ed866 100644
--- a/src/libmpeg2/idct.c
+++ b/src/libmpeg2/idct.c
@@ -55,9 +55,11 @@
#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
-/* idct main entry point */
+/* 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)])
@@ -260,8 +262,26 @@ static void mpeg2_idct_add_c (int16_t * block, uint8_t * dest, int stride)
} 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;
+
#ifdef ARCH_X86
if (mm_accel & MM_ACCEL_X86_MMXEXT) {
#ifdef LOG
@@ -269,13 +289,17 @@ void mpeg2_idct_init (uint32_t mm_accel)
#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_add = mpeg2_idct_add_mmx;
+ mpeg2_idct = mpeg2_idct_mmx;
+ mpeg2_zero_block = mpeg2_zero_block_mmx;
mpeg2_idct_mmx_init ();
} else
#endif
@@ -287,6 +311,7 @@ void mpeg2_idct_init (uint32_t mm_accel)
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
@@ -295,6 +320,7 @@ void mpeg2_idct_init (uint32_t mm_accel)
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");
@@ -314,7 +340,8 @@ void mpeg2_idct_init (uint32_t mm_accel)
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_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_mlib.c b/src/libmpeg2/idct_mlib.c
index bfafd07b1..bb1aad9a8 100644
--- a/src/libmpeg2/idct_mlib.c
+++ b/src/libmpeg2/idct_mlib.c
@@ -54,4 +54,9 @@ void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, int 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_mmx.c b/src/libmpeg2/idct_mmx.c
index bee54e83b..78ab3c547 100644
--- a/src/libmpeg2/idct_mmx.c
+++ b/src/libmpeg2/idct_mmx.c
@@ -691,6 +691,10 @@ void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int 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)
@@ -709,6 +713,16 @@ void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int 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)
{
extern uint8_t mpeg2_scan_norm[64];
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index 2fdbacdce..b6500d1ef 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -22,10 +22,14 @@
/* Structure for the mpeg2dec decoder */
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;
@@ -56,7 +60,8 @@ typedef struct mpeg2dec_s {
/* initialize mpegdec with a opaque user pointer */
-void mpeg2_init (mpeg2dec_t * mpeg2dec);
+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);
diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h
index 5beea9844..069fc9dc1 100644
--- a/src/libmpeg2/mpeg2_internal.h
+++ b/src/libmpeg2/mpeg2_internal.h
@@ -21,13 +21,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "video_out.h"
+
/* macroblock modes */
-#define MACROBLOCK_INTRA 1
-#define MACROBLOCK_PATTERN 2
-#define MACROBLOCK_MOTION_BACKWARD 4
-#define MACROBLOCK_MOTION_FORWARD 8
-#define MACROBLOCK_QUANT 16
-#define DCT_TYPE_INTERLACED 32
+#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
@@ -37,16 +40,16 @@
#define MC_DMV (3*64)
/* picture structure */
-#define TOP_FIELD 1
-#define BOTTOM_FIELD 2
-#define FRAME_PICTURE 3
+#define TOP_FIELD VO_TOP_FIELD
+#define BOTTOM_FIELD VO_BOTTOM_FIELD
+#define FRAME_PICTURE VO_BOTH_FIELDS
-/* picture coding type */
+/* 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];
@@ -61,6 +64,17 @@ typedef struct picture_s {
/* 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 */
@@ -198,12 +212,16 @@ 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 */
@@ -236,5 +254,8 @@ extern mpeg2_mc_t mpeg2_mc_mlib;
/* slice.c */
void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer);
+/* slice_xvmc.c */
+void mpeg2_xvmc_slice (picture_t * picture, int code, uint8_t * buffer);
+
/* stats.c */
void mpeg2_stats (int code, uint8_t * buffer);
diff --git a/src/libmpeg2/slice_xvmc.c b/src/libmpeg2/slice_xvmc.c
new file mode 100644
index 000000000..3e63bd77b
--- /dev/null
+++ b/src/libmpeg2/slice_xvmc.c
@@ -0,0 +1,2066 @@
+/*
+ * slice_xvmc.c
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * 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 <stdio.h>
+#include <string.h> /* memcpy/memset, try to remove */
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "xine_internal.h"
+#include "video_out.h"
+#include "mpeg2_internal.h"
+#include "xineutils.h"
+
+#include "attributes.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)
+
+
+extern mpeg2_mc_t mpeg2_mc;
+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_cpu_state_save) (cpu_state_t * state);
+extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state);
+extern void (* mpeg2_zero_block) (int16_t * block);
+
+#include "vlc.h"
+
+extern uint8_t mpeg2_scan_norm[64];
+extern uint8_t mpeg2_scan_alt[64];
+
+/* original (non-patched) scan tables */
+static 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
+};
+
+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 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;
+ 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;
+ 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 vector, int f_code)
+{
+#if 1
+ unsigned int limit;
+ int sign;
+
+ limit = 16 << f_code;
+
+ if ((unsigned int)(vector + limit) < 2 * limit)
+ return vector;
+ else {
+ sign = ((int32_t)vector) >> 31;
+ return vector - ((2 * limit) ^ sign) + sign;
+ }
+#else
+ return ((int32_t)vector << (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)
+
+ 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)
+
+ 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)
+ 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)
+ 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 val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = picture->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ dest = picture->mc->blockptr;
+
+ /* XvMC's IDCT must use non-patched scan tables */
+ if( picture->mc->xvmc_accel & IDCT_ACCEL ) {
+ if( scan == mpeg2_scan_norm )
+ scan = mpeg2_scan_norm_orig;
+ else
+ scan = mpeg2_scan_alt_orig;
+ }
+
+ 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_xvmc_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;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ dest = picture->mc->blockptr;
+
+ /* XvMC's IDCT must use non-patched scan tables */
+ if( picture->mc->xvmc_accel & IDCT_ACCEL ) {
+ if( scan == mpeg2_scan_norm )
+ scan = mpeg2_scan_norm_orig;
+ else
+ scan = mpeg2_scan_alt_orig;
+ }
+
+ 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_xvmc_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;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ i = -1;
+ mismatch = 1;
+
+ dest = picture->mc->blockptr;
+
+ /* XvMC's IDCT must use non-patched scan tables */
+ if( picture->mc->xvmc_accel & IDCT_ACCEL ) {
+ if( scan == mpeg2_scan_norm )
+ scan = mpeg2_scan_norm_orig;
+ else
+ scan = mpeg2_scan_alt_orig;
+ }
+
+ 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_xvmc_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;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ i = 0;
+
+ dest = picture->mc->blockptr;
+
+ /* XvMC's IDCT must use non-patched scan tables */
+ if( picture->mc->xvmc_accel & IDCT_ACCEL ) {
+ if( scan == mpeg2_scan_norm )
+ scan = mpeg2_scan_norm_orig;
+ else
+ scan = mpeg2_scan_alt_orig;
+ }
+
+ 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_xvmc_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;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ i = -1;
+
+ dest = picture->mc->blockptr;
+
+ /* XvMC's IDCT must use non-patched scan tables */
+ if( picture->mc->xvmc_accel & IDCT_ACCEL ) {
+ if( scan == mpeg2_scan_norm )
+ scan = mpeg2_scan_norm_orig;
+ else
+ scan = mpeg2_scan_alt_orig;
+ }
+
+ 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_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);
+ // memset (picture->mc->blockptr + 1, 0, 63 * sizeof (int16_t));
+ // TODO do we need to zero mem here?
+
+ 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;
+}
+
+#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_y > picture->limit_y_ ## size)) \
+ return; \
+ 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) \
+
+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_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;
+
+ 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_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;
+
+ 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),
+ 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;
+
+ // MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field);
+
+ 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;
+
+ // 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;
+ unsigned int xy_half, offset;
+
+ // 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);
+ dmv_x = get_xvmc_dmv (picture);
+
+ 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;
+ dmv_y = get_xvmc_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);
+
+ xy_half = ((motion_y & 1) << 1) | (motion_x & 1);
+ offset = (picture->offset + (motion_x >> 1) +
+ (picture->v_offset + (motion_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);
+}
+
+// TODO don't need this routine
+static void motion_zero (picture_t * picture, motion_t * motion,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ if(picture->mc->xvmc_accel==0) {
+ 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_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;
+ unsigned int pos_x, pos_y, xy_half;
+
+ 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;
+
+ 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)];
+
+ // 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;
+
+ MOTION (table, ref_field, motion_x, motion_y, 8, 0);
+
+ 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;
+
+ 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_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);
+ other_x = ((motion_x + (motion_x > 0)) >> 1) + get_xvmc_dmv (picture);
+
+ 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;
+ other_y = (((motion_y + (motion_y > 0)) >> 1) + get_xvmc_dmv (picture) +
+ picture->dmv_offset);
+
+ // 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;
+
+ 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_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->copy) { \
+ picture->current_frame->copy (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;
+ 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->copy && 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 == MOTION_ACCEL) {
+ //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->copy == 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 (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_xvmc_init (picture, code))
+ return;
+
+ if (mpeg2_cpu_state_save)
+ mpeg2_cpu_state_save (&cpu_state);
+
+ while (1) {
+ int macroblock_modes;
+ int mba_inc;
+ 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 == MOTION_ACCEL) {
+ // 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->current_frame->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);
+ 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 == MOTION_ACCEL) {
+ // 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;
+
+ picture->current_frame->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;
+
+ picture->current_frame->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);
+ }
+ }
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
diff --git a/src/libmpeg2/xine_decoder.c b/src/libmpeg2/xine_decoder.c
index 7b1313e85..5d2b91df7 100644
--- a/src/libmpeg2/xine_decoder.c
+++ b/src/libmpeg2/xine_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.49 2003/08/05 15:09:23 mroi Exp $
+ * $Id: xine_decoder.c,v 1.50 2003/10/06 21:52:43 miguelfreitas Exp $
*
* stuff needed to turn libmpeg2 into a xine decoder plugin
*/
@@ -137,7 +137,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
this->class = (mpeg2_class_t *) class_gen;
this->mpeg2.stream = stream;
- mpeg2_init (&this->mpeg2);
+ 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;
diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c
index 5558231f7..5569039cc 100644
--- a/src/post/deinterlace/xine_plugin.c
+++ b/src/post/deinterlace/xine_plugin.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_plugin.c,v 1.13 2003/08/15 14:43:29 mroi Exp $
+ * $Id: xine_plugin.c,v 1.14 2003/10/06 21:52:43 miguelfreitas Exp $
*
* advanced video deinterlacer plugin
* Jun/2003 by Miguel Freitas
@@ -44,7 +44,7 @@ post_info_t deinterlace_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 4, "tvtime", XINE_VERSION_CODE, &deinterlace_special_info, &deinterlace_init_plugin },
+ { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 5, "tvtime", XINE_VERSION_CODE, &deinterlace_special_info, &deinterlace_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c
index c5b48ed73..f124ead07 100644
--- a/src/post/goom/xine_goom.c
+++ b/src/post/goom/xine_goom.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_goom.c,v 1.35 2003/09/14 15:45:55 tmattern Exp $
+ * $Id: xine_goom.c,v 1.36 2003/10/06 21:52:43 miguelfreitas Exp $
*
* GOOM post plugin.
*
@@ -122,7 +122,7 @@ post_info_t goom_special_info = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 4, "goom", XINE_VERSION_CODE, &goom_special_info, &goom_init_plugin },
+ { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 5, "goom", XINE_VERSION_CODE, &goom_special_info, &goom_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/post/mosaico/mosaico.c b/src/post/mosaico/mosaico.c
index 7a1d5eec9..8b095769c 100644
--- a/src/post/mosaico/mosaico.c
+++ b/src/post/mosaico/mosaico.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: mosaico.c,v 1.13 2003/08/12 13:56:25 mroi Exp $
+ * $Id: mosaico.c,v 1.14 2003/10/06 21:52:43 miguelfreitas Exp $
*/
/*
@@ -47,7 +47,7 @@ post_info_t mosaico_special_info = { XINE_POST_TYPE_VIDEO_COMPOSE };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "mosaico", MOVERSION, &mosaico_special_info, &mosaico_init_plugin },
+ { PLUGIN_POST, 5, "mosaico", MOVERSION, &mosaico_special_info, &mosaico_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/post/mosaico/switch.c b/src/post/mosaico/switch.c
index cbe2335af..694db8697 100644
--- a/src/post/mosaico/switch.c
+++ b/src/post/mosaico/switch.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: switch.c,v 1.5 2003/08/12 13:56:25 mroi Exp $
+ * $Id: switch.c,v 1.6 2003/10/06 21:52:43 miguelfreitas Exp $
*/
/*
@@ -41,7 +41,7 @@ post_info_t switch_special_info = { XINE_POST_TYPE_VIDEO_COMPOSE };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "switch", SWVERSION, &switch_special_info, &switch_init_plugin },
+ { PLUGIN_POST, 5, "switch", SWVERSION, &switch_special_info, &switch_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/post/planar/boxblur.c b/src/post/planar/boxblur.c
index 5be693e33..7ec51bc55 100644
--- a/src/post/planar/boxblur.c
+++ b/src/post/planar/boxblur.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: boxblur.c,v 1.6 2003/08/15 14:43:29 mroi Exp $
+ * $Id: boxblur.c,v 1.7 2003/10/06 21:52:43 miguelfreitas Exp $
*
* mplayer's boxblur
* Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
@@ -31,17 +31,6 @@
/* plugin class initialization function */
void *boxblur_init_plugin(xine_t *xine, void *);
-#if 0 /* moved to planar.c */
-/* plugin catalog information */
-post_info_t boxblur_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "boxblur", XINE_VERSION_CODE, &boxblur_special_info, &boxblur_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
-
typedef struct post_plugin_boxblur_s post_plugin_boxblur_t;
/*
diff --git a/src/post/planar/denoise3d.c b/src/post/planar/denoise3d.c
index 47570d4a9..024cba960 100644
--- a/src/post/planar/denoise3d.c
+++ b/src/post/planar/denoise3d.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: denoise3d.c,v 1.6 2003/08/15 14:43:30 mroi Exp $
+ * $Id: denoise3d.c,v 1.7 2003/10/06 21:52:43 miguelfreitas Exp $
*
* mplayer's denoise3d
* Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org>
@@ -38,18 +38,6 @@
/* plugin class initialization function */
void *denoise3d_init_plugin(xine_t *xine, void *);
-
-#if 0 /* moved to planar.c */
-/* plugin catalog information */
-post_info_t denoise3d_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "denoise3d", XINE_VERSION_CODE, &denoise3d_special_info, &denoise3d_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
-
typedef struct post_plugin_denoise3d_s post_plugin_denoise3d_t;
diff --git a/src/post/planar/eq.c b/src/post/planar/eq.c
index e51fffe6d..e5991e7ea 100644
--- a/src/post/planar/eq.c
+++ b/src/post/planar/eq.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: eq.c,v 1.5 2003/08/15 14:43:30 mroi Exp $
+ * $Id: eq.c,v 1.6 2003/10/06 21:52:43 miguelfreitas Exp $
*
* mplayer's eq (soft video equalizer)
* Copyright (C) Richard Felker
@@ -119,16 +119,6 @@ static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int
/* plugin class initialization function */
void *eq_init_plugin(xine_t *xine, void *);
-#if 0 /* moved to planar.c */
-/* plugin catalog information */
-post_info_t eq_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "eq", XINE_VERSION_CODE, &eq_special_info, &eq_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
typedef struct post_plugin_eq_s post_plugin_eq_t;
diff --git a/src/post/planar/eq2.c b/src/post/planar/eq2.c
index a02303e55..866f3083b 100644
--- a/src/post/planar/eq2.c
+++ b/src/post/planar/eq2.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: eq2.c,v 1.7 2003/08/19 18:33:43 mroi Exp $
+ * $Id: eq2.c,v 1.8 2003/10/06 21:52:43 miguelfreitas Exp $
*
* mplayer's eq2 (soft video equalizer)
* Software equalizer (brightness, contrast, gamma, saturation)
@@ -264,17 +264,6 @@ void set_saturation (vf_eq2_t *eq2, double s)
/* plugin class initialization function */
void *eq2_init_plugin(xine_t *xine, void *);
-#if 0 /* moved to planar.c */
-/* plugin catalog information */
-post_info_t eq2_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "eq2", XINE_VERSION_CODE, &eq2_special_info, &eq2_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
-
typedef struct post_plugin_eq2_s post_plugin_eq2_t;
/*
diff --git a/src/post/planar/expand.c b/src/post/planar/expand.c
index 91b1d15c4..ea7a6ee60 100644
--- a/src/post/planar/expand.c
+++ b/src/post/planar/expand.c
@@ -61,17 +61,6 @@
/* plugin class initialization function */
void *expand_init_plugin(xine_t *xine, void *);
-#if 0 /* moved to planar.c */
-/* plugin catalog information */
-post_info_t expand_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "expand", XINE_VERSION_CODE, &expand_special_info, &expand_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
-
/* plugin structures */
typedef struct expand_parameters_s {
int enable_automatic_shift;
diff --git a/src/post/planar/invert.c b/src/post/planar/invert.c
index c81d3e12a..26bc4b7b9 100644
--- a/src/post/planar/invert.c
+++ b/src/post/planar/invert.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: invert.c,v 1.12 2003/08/12 13:56:26 mroi Exp $
+ * $Id: invert.c,v 1.13 2003/10/06 21:52:43 miguelfreitas Exp $
*/
/*
@@ -31,19 +31,6 @@
/* plugin class initialization function */
void *invert_init_plugin(xine_t *xine, void *);
-#if 0 /* moved to planar.c */
-
-/* plugin catalog information */
-post_info_t invert_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "invert", XINE_VERSION_CODE, &invert_special_info, &invert_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-
-#endif
-
/* plugin structure */
typedef struct post_invert_out_s post_invert_out_t;
struct post_invert_out_s {
diff --git a/src/post/planar/planar.c b/src/post/planar/planar.c
index 7ab3ad521..89f9e76bb 100644
--- a/src/post/planar/planar.c
+++ b/src/post/planar/planar.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: planar.c,v 1.2 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: planar.c,v 1.3 2003/10/06 21:52:44 miguelfreitas Exp $
*
* catalog for planar post plugins
*/
@@ -49,13 +49,13 @@ post_info_t unsharp_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "expand", XINE_VERSION_CODE+1, &expand_special_info, &expand_init_plugin },
- { PLUGIN_POST, 4, "invert", XINE_VERSION_CODE+1, &invert_special_info, &invert_init_plugin },
- { PLUGIN_POST, 4, "eq", XINE_VERSION_CODE, &eq_special_info, &eq_init_plugin },
- { PLUGIN_POST, 4, "denoise3d", XINE_VERSION_CODE, &denoise3d_special_info, &denoise3d_init_plugin },
- { PLUGIN_POST, 4, "boxblur", XINE_VERSION_CODE, &boxblur_special_info, &boxblur_init_plugin },
- { PLUGIN_POST, 4, "eq2", XINE_VERSION_CODE, &eq2_special_info, &eq2_init_plugin },
- { PLUGIN_POST, 4, "unsharp", XINE_VERSION_CODE, &unsharp_special_info, &unsharp_init_plugin },
+ { PLUGIN_POST, 5, "expand", XINE_VERSION_CODE+1, &expand_special_info, &expand_init_plugin },
+ { PLUGIN_POST, 5, "invert", XINE_VERSION_CODE+1, &invert_special_info, &invert_init_plugin },
+ { PLUGIN_POST, 5, "eq", XINE_VERSION_CODE, &eq_special_info, &eq_init_plugin },
+ { PLUGIN_POST, 5, "denoise3d", XINE_VERSION_CODE, &denoise3d_special_info, &denoise3d_init_plugin },
+ { PLUGIN_POST, 5, "boxblur", XINE_VERSION_CODE, &boxblur_special_info, &boxblur_init_plugin },
+ { PLUGIN_POST, 5, "eq2", XINE_VERSION_CODE, &eq2_special_info, &eq2_init_plugin },
+ { PLUGIN_POST, 5, "unsharp", XINE_VERSION_CODE, &unsharp_special_info, &unsharp_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/post/planar/unsharp.c b/src/post/planar/unsharp.c
index 61defa672..499fba98f 100644
--- a/src/post/planar/unsharp.c
+++ b/src/post/planar/unsharp.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: unsharp.c,v 1.6 2003/08/15 14:43:30 mroi Exp $
+ * $Id: unsharp.c,v 1.7 2003/10/06 21:52:44 miguelfreitas Exp $
*
* mplayer's unsharp
* Copyright (C) 2002 Rémi Guyomarch <rguyom@pobox.com>
@@ -130,17 +130,6 @@ static void unsharp( uint8_t *dst, uint8_t *src, int dstStride, int srcStride, i
/* plugin class initialization function */
void *unsharp_init_plugin(xine_t *xine, void *);
-#if 0 /* moved to planar.c */
-/* plugin catalog information */
-post_info_t unsharp_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "unsharp", XINE_VERSION_CODE, &unsharp_special_info, &unsharp_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
-
typedef struct post_plugin_unsharp_s post_plugin_unsharp_t;
/*
diff --git a/src/post/visualizations/fooviz.c b/src/post/visualizations/fooviz.c
index 505a10bc6..1f0f93c33 100644
--- a/src/post/visualizations/fooviz.c
+++ b/src/post/visualizations/fooviz.c
@@ -23,7 +23,7 @@
* process. It simply paints the screen a solid color and rotates through
* colors on each iteration.
*
- * $Id: fooviz.c,v 1.9 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: fooviz.c,v 1.10 2003/10/06 21:52:44 miguelfreitas Exp $
*
*/
@@ -373,6 +373,6 @@ post_info_t fooviz_special_info = { XINE_POST_TYPE_AUDIO_VISUALIZATION };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "fooviz", XINE_VERSION_CODE, &fooviz_special_info, &fooviz_init_plugin },
+ { PLUGIN_POST, 5, "fooviz", XINE_VERSION_CODE, &fooviz_special_info, &fooviz_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/post/visualizations/visualizations.c b/src/post/visualizations/visualizations.c
index 447518ff3..65057cb97 100644
--- a/src/post/visualizations/visualizations.c
+++ b/src/post/visualizations/visualizations.c
@@ -19,7 +19,7 @@
*
* This file contains plugin entries for several visualization post plugins.
*
- * $Id: visualizations.c,v 1.5 2003/09/14 12:37:30 tmattern Exp $
+ * $Id: visualizations.c,v 1.6 2003/10/06 21:52:44 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -46,8 +46,8 @@ post_info_t fftgraph_special_info = { XINE_POST_TYPE_AUDIO_VISUALIZATION };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, 4, "oscope", XINE_VERSION_CODE, &oscope_special_info, &oscope_init_plugin },
- { PLUGIN_POST, 4, "fftscope", XINE_VERSION_CODE, &fftscope_special_info, &fftscope_init_plugin },
- { PLUGIN_POST, 4, "fftgraph", XINE_VERSION_CODE, &fftgraph_special_info, &fftgraph_init_plugin },
+ { PLUGIN_POST, 5, "oscope", XINE_VERSION_CODE, &oscope_special_info, &oscope_init_plugin },
+ { PLUGIN_POST, 5, "fftscope", XINE_VERSION_CODE, &fftscope_special_info, &fftscope_init_plugin },
+ { PLUGIN_POST, 5, "fftgraph", XINE_VERSION_CODE, &fftgraph_special_info, &fftgraph_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index 956c5c7fa..21afcfe51 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -20,6 +20,9 @@ syncfb_module = xineplug_vo_out_syncfb.la
if HAVE_XV
xv_module = xineplug_vo_out_xv.la
endif
+if HAVE_XVMC
+xvmc_module = xineplug_vo_out_xvmc.la
+endif
#if HAVE_OPENGL
#opengl_module = xineplug_vo_out_opengl.la
#endif
@@ -59,7 +62,7 @@ endif
#lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(directfb_module) \
# $(syncfb_module) $(fb_module) $(opengl_module) $(sdl_module) $(vidix_module)
-lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(aa_module) $(pgx64_module) \
+lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) $(aa_module) $(pgx64_module) \
$(vidix_module) $(fb_module) $(sdl_module) $(syncfb_module) \
$(stk_module) $(directfb_module) xineplug_vo_out_none.la
@@ -70,8 +73,18 @@ xineplug_vo_out_xv_la_LIBADD = \
-lXext \
$(XINE_LIB)
+xineplug_vo_out_xvmc_la_SOURCES = deinterlace.c alphablend.c video_out_xvmc.c
+xineplug_vo_out_xvmc_la_LIBADD = \
+ $(XV_LIB) \
+ $(XVMC_LIB) \
+ $(X_LIBS) \
+ -lXext \
+ $(XINE_LIB)
+
xineplug_vo_out_xv_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+xineplug_vo_out_xvmc_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+
xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
alphablend.c video_out_xshm.c
xineplug_vo_out_xshm_la_LIBADD = $(X_LIBS) -lXext \
diff --git a/src/video_out/video_out_aa.c b/src/video_out/video_out_aa.c
index 77a28ce72..9c0e9e05a 100644
--- a/src/video_out/video_out_aa.c
+++ b/src/video_out/video_out_aa.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_aa.c,v 1.36 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: video_out_aa.c,v 1.37 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_aa.c, ascii-art output plugin for xine
*
@@ -328,6 +328,6 @@ static vo_info_t vo_info_aa = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "aa", XINE_VERSION_CODE, &vo_info_aa, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "aa", XINE_VERSION_CODE, &vo_info_aa, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c
index 7f2d38291..a8282b5c5 100644
--- a/src/video_out/video_out_directfb.c
+++ b/src/video_out/video_out_directfb.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_directfb.c,v 1.20 2003/08/09 22:44:09 hadess Exp $
+ * $Id: video_out_directfb.c,v 1.21 2003/10/06 21:52:44 miguelfreitas Exp $
*
* DirectFB based output plugin.
* Rich Wareham <richwareham@users.sourceforge.net>
@@ -591,7 +591,7 @@ static vo_info_t vo_info_directfb = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "DirectFB", XINE_VERSION_CODE, &vo_info_directfb, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "DirectFB", XINE_VERSION_CODE, &vo_info_directfb, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c
index 0f8e78c71..1c514f518 100755
--- a/src/video_out/video_out_directx.c
+++ b/src/video_out/video_out_directx.c
@@ -1262,6 +1262,6 @@ static vo_info_t vo_info_win32 = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "vo_directx", XINE_VERSION_CODE, &vo_info_win32, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "vo_directx", XINE_VERSION_CODE, &vo_info_win32, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c
index a9d4f364e..ee65f19d0 100644
--- a/src/video_out/video_out_fb.c
+++ b/src/video_out/video_out_fb.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_fb.c,v 1.27 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: video_out_fb.c,v 1.28 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_fb.c, frame buffer xine driver by Miguel Freitas
*
@@ -1053,7 +1053,7 @@ plugin_info_t xine_plugin_info[] =
/* type, API, "name", version, special_info, init_function */
{
PLUGIN_VIDEO_OUT,
- 16,
+ 17,
"fb",
XINE_VERSION_CODE,
&vo_info_fb, fb_init_class
diff --git a/src/video_out/video_out_none.c b/src/video_out/video_out_none.c
index 14dfdde57..7d99713ea 100644
--- a/src/video_out/video_out_none.c
+++ b/src/video_out/video_out_none.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_none.c,v 1.15 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: video_out_none.c,v 1.16 2003/10/06 21:52:44 miguelfreitas Exp $
*
* Was originally part of toxine frontend.
* ...but has now been adapted to xine coding style standards ;)
@@ -302,6 +302,6 @@ static vo_info_t vo_info_none = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "none", XINE_VERSION_CODE, &vo_info_none, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "none", XINE_VERSION_CODE, &vo_info_none, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index 3d1ba2095..f2282eaf5 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_opengl.c,v 1.27 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: video_out_opengl.c,v 1.28 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_glut.c, glut based OpenGL rendering interface for xine
* Matthias Hopf <mat@mshopf.de>
@@ -1000,7 +1000,7 @@ static vo_info_t vo_info_opengl = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "opengl", XINE_VERSION_CODE,
+ { PLUGIN_VIDEO_OUT, 17, "opengl", XINE_VERSION_CODE,
&vo_info_opengl, opengl_init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_pgx64.c b/src/video_out/video_out_pgx64.c
index eb0a413b8..28bde24f4 100644
--- a/src/video_out/video_out_pgx64.c
+++ b/src/video_out/video_out_pgx64.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_pgx64.c,v 1.38 2003/10/05 16:22:19 komadori Exp $
+ * $Id: video_out_pgx64.c,v 1.39 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_pgx64.c, Sun PGX64/PGX24 output plugin for xine
*
@@ -1006,6 +1006,6 @@ static pgx64_driver_class_t* pgx64_init_class(xine_t *xine, void *visual_gen)
}
plugin_info_t xine_plugin_info[] = {
- {PLUGIN_VIDEO_OUT, 16, "pgx64", XINE_VERSION_CODE, &vo_info_pgx64, (void*)pgx64_init_class},
+ {PLUGIN_VIDEO_OUT, 17, "pgx64", XINE_VERSION_CODE, &vo_info_pgx64, (void*)pgx64_init_class},
{PLUGIN_NONE, 0, "", 0, NULL, NULL}
};
diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c
index 8d6a3e6f5..50ff3753f 100644
--- a/src/video_out/video_out_sdl.c
+++ b/src/video_out/video_out_sdl.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_sdl.c,v 1.26 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: video_out_sdl.c,v 1.27 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_sdl.c, Simple DirectMedia Layer
*
@@ -596,6 +596,6 @@ static vo_info_t vo_info_sdl = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "sdl", XINE_VERSION_CODE, &vo_info_sdl, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "sdl", XINE_VERSION_CODE, &vo_info_sdl, init_class },
{ PLUGIN_NONE, 0, "" , 0 , NULL, NULL}
};
diff --git a/src/video_out/video_out_stk.c b/src/video_out/video_out_stk.c
index 96f678dd6..29894180d 100644
--- a/src/video_out/video_out_stk.c
+++ b/src/video_out/video_out_stk.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_stk.c,v 1.3 2003/09/13 17:20:50 miguelfreitas Exp $
+ * $Id: video_out_stk.c,v 1.4 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_stk.c, Libstk Surface Video Driver
* more info on Libstk at http://www.libstk.org
@@ -461,7 +461,7 @@ static vo_info_t vo_info_stk = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "stk", XINE_VERSION_CODE, &vo_info_stk, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "stk", XINE_VERSION_CODE, &vo_info_stk, init_class },
{ PLUGIN_NONE, 0, "" , 0 , NULL, NULL}
};
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
index 401be3cff..32376315d 100644
--- a/src/video_out/video_out_syncfb.c
+++ b/src/video_out/video_out_syncfb.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_syncfb.c,v 1.88 2003/08/25 21:51:48 f1rmb Exp $
+ * $Id: video_out_syncfb.c,v 1.89 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine
*
@@ -1057,7 +1057,7 @@ static vo_info_t vo_info_syncfb = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "SyncFB", XINE_VERSION_CODE, &vo_info_syncfb, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "SyncFB", XINE_VERSION_CODE, &vo_info_syncfb, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c
index 0b6a4d6b7..b7017c233 100644
--- a/src/video_out/video_out_vidix.c
+++ b/src/video_out/video_out_vidix.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_vidix.c,v 1.46 2003/09/22 21:34:10 jstembridge Exp $
+ * $Id: video_out_vidix.c,v 1.47 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_vidix.c
*
@@ -1233,10 +1233,10 @@ static vo_info_t vo_info_vidixfb = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
#ifdef HAVE_X11
- { PLUGIN_VIDEO_OUT, 16, "vidix", XINE_VERSION_CODE, &vo_info_vidix, vidix_init_class },
+ { PLUGIN_VIDEO_OUT, 17, "vidix", XINE_VERSION_CODE, &vo_info_vidix, vidix_init_class },
#endif
#ifdef HAVE_FB
- { PLUGIN_VIDEO_OUT, 16, "vidixfb", XINE_VERSION_CODE, &vo_info_vidixfb, vidixfb_init_class },
+ { PLUGIN_VIDEO_OUT, 17, "vidixfb", XINE_VERSION_CODE, &vo_info_vidixfb, vidixfb_init_class },
#endif
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index dece34455..a7912acd5 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xshm.c,v 1.112 2003/08/04 03:47:11 miguelfreitas Exp $
+ * $Id: video_out_xshm.c,v 1.113 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -1289,6 +1289,6 @@ static vo_info_t vo_info_xshm = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "xshm", XINE_VERSION_CODE, &vo_info_xshm, xshm_init_class },
+ { PLUGIN_VIDEO_OUT, 17, "xshm", XINE_VERSION_CODE, &vo_info_xshm, xshm_init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index ad7b1b326..5fc7df389 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xv.c,v 1.173 2003/08/29 23:10:13 miguelfreitas Exp $
+ * $Id: video_out_xv.c,v 1.174 2003/10/06 21:52:44 miguelfreitas Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -1474,7 +1474,7 @@ static vo_info_t vo_info_xv = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 16, "xv", XINE_VERSION_CODE, &vo_info_xv, init_class },
+ { PLUGIN_VIDEO_OUT, 17, "xv", XINE_VERSION_CODE, &vo_info_xv, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c
new file mode 100644
index 000000000..2a3a642b1
--- /dev/null
+++ b/src/video_out/video_out_xvmc.c
@@ -0,0 +1,1908 @@
+/*
+ * Copyright (C) 2000-2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: video_out_xvmc.c,v 1.2 2003/10/06 21:52:44 miguelfreitas Exp $
+ *
+ * video_out_xvmc.c, X11 video motion compensation extension interface for xine
+ *
+ * based on mpeg2dec code from
+ * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * XvMC image support by Jack Kelliher
+ *
+ * TODO:
+ * - support non-XvMC output, probably falling back to Xv.
+ * - support XvMC overlays for spu/osd
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_XVMC
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+#if defined(__FreeBSD__)
+#include <machine/param.h>
+#endif
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+
+#include <X11/extensions/XvMClib.h>
+#include <X11/extensions/XvMC.h>
+
+#include "xine.h"
+#include "video_out.h"
+#include "xine_internal.h"
+
+// TODO - delete these?
+#include "alphablend.h"
+#include "deinterlace.h"
+
+#include "xineutils.h"
+#include "vo_scale.h"
+
+/*
+#define LOG
+*/
+//#define LOG1
+//#define LOG
+//#define DLOG
+
+//#define PRINTDATA
+//#define PRINTFRAME
+
+#define MAX_NUM_FRAMES 8
+
+typedef struct xvmc_macroblock_s {
+ xine_macroblocks_t xine_mc;
+ XvMCBlockArray *blocks; // pointer to memory for dct block array
+ int num_blocks;
+ XvMCMacroBlock *macroblockptr; // pointer to current macro block
+ XvMCMacroBlock *macroblockbaseptr; // pointer to base MacroBlock in MB array
+ XvMCMacroBlockArray *macro_blocks; // pointer to memory for macroblock array
+ int slices;
+} xvmc_macroblocks_t;
+
+typedef struct cxid_s cxid_t;
+struct cxid_s {
+ void *xid;
+};
+
+typedef struct xvmc_driver_s xvmc_driver_t;
+
+typedef struct {
+ int value;
+ int min;
+ int max;
+ Atom atom;
+
+ cfg_entry_t *entry;
+
+ xvmc_driver_t *this;
+} xvmc_property_t;
+
+
+typedef struct {
+ vo_frame_t vo_frame;
+
+ int width, height, format;
+ double ratio;
+
+ XvMCSurface surface;
+
+ // temporary Xv only storage
+ XvImage *image;
+ XShmSegmentInfo shminfo;
+
+} xvmc_frame_t;
+
+
+struct xvmc_driver_s {
+
+ vo_driver_t vo_driver;
+
+ config_values_t *config;
+
+ /* X11 / XvMC related stuff */
+ Display *display;
+ int screen;
+ Drawable drawable;
+ unsigned int xvmc_format_yv12;
+ unsigned int xvmc_format_yuy2;
+ XVisualInfo vinfo;
+ GC gc;
+ XvPortID xv_port;
+ XvMCContext context;
+ xvmc_frame_t *frames[MAX_NUM_FRAMES];
+
+ int surface_type_id;
+ int max_surface_width;
+ int max_surface_height;
+ int num_frame_buffers;
+
+ int surface_width;
+ int surface_height;
+ int surface_ratio;
+ int surface_format;
+ int surface_flags;
+ short acceleration;
+
+ cxid_t context_id;
+ xvmc_macroblocks_t macroblocks;
+
+ /* all scaling information goes here */
+ vo_scale_t sc;
+
+
+ XColor black;
+ int expecting_event; /* completion event handling */
+
+ /* display anatomy */
+ double display_ratio; /* given by visual parameter
+ from init function */
+
+ xvmc_property_t props[VO_NUM_PROPERTIES];
+ uint32_t capabilities;
+
+
+ xvmc_frame_t *recent_frames[VO_NUM_RECENT_FRAMES];
+ xvmc_frame_t *cur_frame;
+ vo_overlay_t *overlay;
+
+ /* TODO CLEAN THIS UP all unused vars sizes moved to vo_scale */
+
+ /* size / aspect ratio calculations */
+
+ /*
+ * "delivered" size:
+ * frame dimension / aspect as delivered by the decoder
+ * used (among other things) to detect frame size changes
+ */
+
+ int delivered_duration;
+
+ /*
+ * "ideal" size :
+ * displayed width/height corrected by aspect ratio
+ */
+
+ double ratio_factor; /* output frame must fullfill:
+ height = width * ratio_factor */
+
+
+ xvmc_frame_t deinterlace_frame;
+ int deinterlace_method;
+ int deinterlace_enabled;
+
+ void *user_data;
+
+ /* gui callback */
+
+ void (*frame_output_cb) (void *user_data,
+ int video_width, int video_height,
+ int *dest_x, int *dest_y,
+ int *dest_height, int *dest_width,
+ int *win_x, int *win_y);
+
+ char scratch[256];
+
+ int use_colorkey;
+ uint32_t colorkey;
+};
+
+
+typedef struct {
+ video_driver_class_t driver_class;
+
+ config_values_t *config;
+ XvPortID xv_port;
+ XvAdaptorInfo *adaptor_info;
+ unsigned int adaptor_num;
+
+ int surface_type_id;
+ unsigned int max_surface_width;
+ unsigned int max_surface_height;
+ short acceleration;
+} xvmc_class_t;
+
+int gX11Fail;
+
+static void xvmc_render_macro_blocks(vo_frame_t *current_image,
+ vo_frame_t *backward_ref_image,
+ vo_frame_t *forward_ref_image,
+ int picture_structure,
+ int second_field,
+ xvmc_macroblocks_t *macroblocks);
+
+
+/*********************** XVMC specific routines *********************/
+
+/**************************************************************************/
+
+static void calc_DMV(DMV,dmvector,mvx,mvy,picture_structure,top_field_first)
+int DMV[][2];
+int *dmvector; /* differential motion vector */
+int mvx, mvy; /* decoded mv components (always in field format) */
+int picture_structure;
+int top_field_first;
+{
+ if (picture_structure==VO_BOTH_FIELDS)
+ {
+ if (top_field_first)
+ {
+ /* vector for prediction of top field from bottom field */
+ DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
+ DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
+
+ /* vector for prediction of bottom field from top field */
+ DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
+ DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
+ }
+ else
+ {
+ /* vector for prediction of top field from bottom field */
+ DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
+ DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
+
+ /* vector for prediction of bottom field from top field */
+ DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
+ DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
+ }
+ }
+ else
+ {
+ /* vector for prediction from field of opposite 'parity' */
+ DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
+ DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
+
+ /* correct for vertical field shift */
+ if (picture_structure==VO_TOP_FIELD)
+ DMV[0][1]--;
+ else
+ DMV[0][1]++;
+ }
+}
+
+static void xvmc_proc_macro_block(
+ int x,
+ int y,
+ int mb_type,
+ int motion_type,
+ // int (*PMV)[2][2],
+ int (*mv_field_sel)[2],
+ int *dmvector,
+ int cbp,
+ int dct_type,
+ vo_frame_t *current_frame,
+ vo_frame_t *forward_ref_frame,
+ vo_frame_t *backward_ref_frame,
+ int picture_structure,
+ int second_field,
+ int (*f_mot_pmv)[2],
+ int (*b_mot_pmv)[2])
+{
+ xvmc_driver_t *this = (xvmc_driver_t *) current_frame->driver;
+ xvmc_macroblocks_t * mbs = &this->macroblocks;
+ int top_field_first=current_frame->top_field_first;
+ int picture_coding_type = current_frame->picture_coding_type;
+
+ mbs->macroblockptr->x = x;
+ mbs->macroblockptr->y = y;
+
+ if(mb_type & XINE_MACROBLOCK_INTRA) {
+ mbs->macroblockptr->macroblock_type = XVMC_MB_TYPE_INTRA;
+ } else {
+ mbs->macroblockptr->macroblock_type = 0;
+ /* XvMC doesn't support skips */
+ if(!(mb_type & (XINE_MACROBLOCK_MOTION_BACKWARD | XINE_MACROBLOCK_MOTION_FORWARD))) {
+ mb_type |= XINE_MACROBLOCK_MOTION_FORWARD;
+ motion_type = (picture_structure==VO_BOTH_FIELDS) ? XINE_MC_FRAME : XINE_MC_FIELD;
+ mbs->macroblockptr->PMV[0][0][0] = 0;
+ mbs->macroblockptr->PMV[0][0][1] = 0;
+ } else {
+ if(mb_type & XINE_MACROBLOCK_MOTION_BACKWARD) {
+ mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD;
+ mbs->macroblockptr->PMV[0][1][0] =
+ b_mot_pmv[0][0];
+ mbs->macroblockptr->PMV[0][1][1] =
+ b_mot_pmv[0][1];
+ mbs->macroblockptr->PMV[1][1][0] =
+ b_mot_pmv[1][0];
+ mbs->macroblockptr->PMV[1][1][1] =
+ b_mot_pmv[1][1];
+
+ }
+ if(mb_type & XINE_MACROBLOCK_MOTION_FORWARD) {
+ mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD;
+ mbs->macroblockptr->PMV[0][0][0] =
+ f_mot_pmv[0][0];
+ mbs->macroblockptr->PMV[0][0][1] =
+ f_mot_pmv[0][1];
+ mbs->macroblockptr->PMV[1][0][0] =
+ f_mot_pmv[1][0];
+ mbs->macroblockptr->PMV[1][0][1] =
+ f_mot_pmv[1][1];
+ }
+ }
+ if((mb_type & XINE_MACROBLOCK_PATTERN) && cbp)
+ mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_PATTERN;
+
+ mbs->macroblockptr->motion_type = motion_type;
+
+ if(motion_type == XINE_MC_DMV) {
+ int DMV[2][2];
+
+ if(picture_structure==VO_BOTH_FIELDS) {
+ calc_DMV(DMV,dmvector, f_mot_pmv[0][0],
+ f_mot_pmv[0][1]>>1, picture_structure,
+ top_field_first);
+
+ mbs->macroblockptr->PMV[1][0][0] = DMV[0][0];
+ mbs->macroblockptr->PMV[1][0][1] = DMV[0][1];
+ mbs->macroblockptr->PMV[1][1][0] = DMV[1][0];
+ mbs->macroblockptr->PMV[1][1][1] = DMV[1][1];
+ } else {
+ calc_DMV(DMV,dmvector, f_mot_pmv[0][0],
+ f_mot_pmv[0][1]>>1, picture_structure,
+ top_field_first);
+
+ mbs->macroblockptr->PMV[0][1][0] = DMV[0][0];
+ mbs->macroblockptr->PMV[0][1][1] = DMV[0][1];
+ }
+ }
+
+ if((motion_type == XINE_MC_FIELD) || (motion_type == XINE_MC_16X8)) {
+ mbs->macroblockptr->motion_vertical_field_select = 0;
+ if(mv_field_sel[0][0])
+ mbs->macroblockptr->motion_vertical_field_select |= 1;
+ if(mv_field_sel[0][1])
+ mbs->macroblockptr->motion_vertical_field_select |= 2;
+ if(mv_field_sel[1][0])
+ mbs->macroblockptr->motion_vertical_field_select |= 4;
+ if(mv_field_sel[1][1])
+ mbs->macroblockptr->motion_vertical_field_select |= 8;
+ }
+ } // else of if(mb_type & XINE_MACROBLOCK_INTRA)
+
+ mbs->macroblockptr->index = ((unsigned long)mbs->xine_mc.blockptr -
+ (unsigned long)mbs->xine_mc.blockbaseptr) >> 7;
+
+ mbs->macroblockptr->dct_type = dct_type;
+ mbs->macroblockptr->coded_block_pattern = cbp;
+
+ cbp &= 0x3F;
+ mbs->macroblockptr->coded_block_pattern = cbp;
+ while(cbp) {
+ if(cbp & 1) mbs->macroblockptr->index--;
+ cbp >>= 1;
+ }
+
+#ifdef PRINTDATA
+ printf("\n");
+ printf("-- %04d %04d %02x %02x %02x %02x",mbs->macroblockptr->x,mbs->macroblockptr->y,mbs->macroblockptr->macroblock_type,
+ mbs->macroblockptr->motion_type,mbs->macroblockptr->motion_vertical_field_select,mbs->macroblockptr->dct_type);
+ printf(" [%04d %04d %04d %04d %04d %04d %04d %04d] ",
+ mbs->macroblockptr->PMV[0][0][0],mbs->macroblockptr->PMV[0][0][1],mbs->macroblockptr->PMV[0][1][0],mbs->macroblockptr->PMV[0][1][1],
+ mbs->macroblockptr->PMV[1][0][0],mbs->macroblockptr->PMV[1][0][1],mbs->macroblockptr->PMV[1][1][0],mbs->macroblockptr->PMV[1][1][1]);
+
+ printf(" %04d %04x\n",mbs->macroblockptr->index,mbs->macroblockptr->coded_block_pattern);
+
+#endif
+
+ mbs->num_blocks++;
+ mbs->macroblockptr++;
+
+ if(mbs->num_blocks == mbs->slices) {
+#ifdef PRINTDATA
+ printf("macroblockptr %lx", mbs->macroblockptr);
+ printf("** RenderSurface %04d %04x\n",picture_structure,
+ second_field ? XVMC_SECOND_FIELD : 0);
+ fflush(stdout);
+#endif
+#ifdef PRINTFRAME
+ printf(" target %08x past %08x future %08x\n",
+ current_frame,
+ forward_ref_frame,
+ backward_ref_frame);
+#endif
+#ifdef PRINTFRAME
+ if (picture_coding_type == XINE_PICT_P_TYPE)
+ printf(" coding type P_TYPE\n");
+ if (picture_coding_type == XINE_PICT_I_TYPE)
+ printf(" coding type I_TYPE\n");
+ if (picture_coding_type == XINE_PICT_B_TYPE)
+ printf(" coding type B_TYPE\n");
+ if (picture_coding_type == XINE_PICT_D_TYPE)
+ printf(" coding type D_TYPE\n");
+ fflush(stdout);
+#endif
+
+ if (picture_coding_type == XINE_PICT_B_TYPE)
+ xvmc_render_macro_blocks(
+ current_frame,
+ backward_ref_frame,
+ forward_ref_frame,
+ picture_structure,
+ second_field ? XVMC_SECOND_FIELD : 0,
+ mbs);
+ if (picture_coding_type == XINE_PICT_P_TYPE)
+ xvmc_render_macro_blocks(
+ current_frame,
+ NULL,
+ forward_ref_frame,
+ picture_structure,
+ second_field ? XVMC_SECOND_FIELD : 0,
+ mbs);
+ if (picture_coding_type == XINE_PICT_I_TYPE)
+ xvmc_render_macro_blocks(
+ current_frame,
+ NULL,
+ NULL,
+ picture_structure,
+ second_field ? XVMC_SECOND_FIELD : 0,
+ mbs);
+
+ mbs->num_blocks = 0;
+ mbs->macroblockptr = mbs->macroblockbaseptr;
+ mbs->xine_mc.blockptr = mbs->xine_mc.blockbaseptr;
+ }
+}
+
+static uint32_t xvmc_get_capabilities (vo_driver_t *this_gen) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_get_capabilities\n");
+#endif
+
+ return this->capabilities;
+}
+
+static void xvmc_frame_field (vo_frame_t *vo_img, int which_field) {
+ xvmc_driver_t *this = (xvmc_driver_t *) vo_img->driver;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_frame_field\n");
+#endif
+ this->macroblocks.num_blocks = 0;
+ this->macroblocks.macroblockptr = this->macroblocks.macroblockbaseptr;
+ this->macroblocks.xine_mc.blockptr = this->macroblocks.xine_mc.blockbaseptr;
+}
+
+static void xvmc_frame_dispose (vo_frame_t *vo_img) {
+
+ xvmc_frame_t *frame = (xvmc_frame_t *) vo_img ;
+ xvmc_driver_t *this = (xvmc_driver_t *) vo_img->driver;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_frame_dispose\n");
+#endif
+
+ // TODO - clean up of images/surfaces and frames
+ // Note this function is not really needed
+ // set_context does the work
+
+ if (frame->image) {
+ XLockDisplay (this->display);
+ XFree (frame->image);
+ XUnlockDisplay (this->display);
+ }
+
+ free (frame);
+}
+
+static void xvmc_render_macro_blocks(vo_frame_t *current_image,
+ vo_frame_t *backward_ref_image,
+ vo_frame_t *forward_ref_image,
+ int picture_structure,
+ int second_field,
+ xvmc_macroblocks_t *macroblocks) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) current_image->driver;
+ xvmc_frame_t *current_frame = (xvmc_frame_t *) current_image;
+ xvmc_frame_t *forward_frame = (xvmc_frame_t *) forward_ref_image;
+ xvmc_frame_t *backward_frame = (xvmc_frame_t *) backward_ref_image;
+
+
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_render_macro_blocks\n");
+ printf (" slices %d 0x%08lx 0x%08lx 0x%08lx\n",
+ macroblocks->slices,
+ (long) current_frame, (long) backward_frame,
+ (long) forward_frame);
+
+ // printf (" slices %d 0x%08lx 0x%08lx 0x%08lx\n",macroblocks->slices,
+ // (long) current_frame->surface, (long) backward_frame->surface,
+ // (long) forward_frame->surface);
+ fflush(stdout);
+#endif
+
+ /* XvMCSyncSurface(this->display,&current_frame->surface); */
+ if(forward_frame) {
+ if(backward_frame) {
+ XvMCRenderSurface(this->display, &this->context, picture_structure,
+ &current_frame->surface,
+ &forward_frame->surface,
+ &backward_frame->surface,
+ second_field,
+ macroblocks->slices, 0, macroblocks->macro_blocks,
+ macroblocks->blocks);
+ } else {
+ XvMCRenderSurface(this->display, &this->context, picture_structure,
+ &current_frame->surface,
+ &forward_frame->surface,
+ NULL,
+ second_field,
+ macroblocks->slices, 0, macroblocks->macro_blocks,
+ macroblocks->blocks);
+ }
+ } else {
+ if(backward_frame) {
+ XvMCRenderSurface(this->display, &this->context, picture_structure,
+ &current_frame->surface,
+ NULL,
+ &backward_frame->surface,
+ second_field,
+ macroblocks->slices, 0, macroblocks->macro_blocks,
+ macroblocks->blocks);
+ } else {
+ XvMCRenderSurface(this->display, &this->context, picture_structure,
+ &current_frame->surface,
+ NULL,
+ NULL,
+ second_field,
+ macroblocks->slices, 0, macroblocks->macro_blocks,
+ macroblocks->blocks);
+ }
+ }
+
+ // XvMCFlushSurface(this->display, &current_frame->surface);
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_render_macro_blocks done\n");
+ fflush(stdout);
+#endif
+}
+
+static vo_frame_t *xvmc_alloc_frame (vo_driver_t *this_gen) {
+
+ xvmc_frame_t *frame ;
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_alloc_frame\n");
+#endif
+
+ frame = (xvmc_frame_t *) malloc (sizeof (xvmc_frame_t));
+ memset (frame, 0, sizeof(xvmc_frame_t));
+
+ if (frame == NULL) {
+ printf ("xvmc_alloc_frame: out of memory\n");
+ return (NULL);
+ }
+
+ // keep track of frames and how many frames alocated.
+ this->frames[this->num_frame_buffers++] = frame;
+
+ pthread_mutex_init (&frame->vo_frame.mutex, NULL);
+
+ /*
+ * supply required functions
+ */
+
+ frame->vo_frame.copy = NULL;
+ frame->vo_frame.field = xvmc_frame_field;
+ frame->vo_frame.dispose = xvmc_frame_dispose;
+ frame->vo_frame.proc_macro_block = xvmc_proc_macro_block;
+
+ frame->vo_frame.driver = this_gen;
+
+ return (vo_frame_t *) frame;
+}
+
+static cxid_t *xvmc_set_context (xvmc_driver_t *this,
+ uint32_t width, uint32_t height,
+ double ratio, int format, int flags,
+ xine_macroblocks_t *macro_blocks) {
+
+ int result = 0;
+ int i;
+ int slices = 1;
+ xvmc_macroblocks_t *macroblocks = (xvmc_macroblocks_t *) macro_blocks;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_set_context %dx%d %04x\n",width,height,format);
+#endif
+
+ //initialize block & macro block pointers first time
+ if(macroblocks->blocks == NULL || macroblocks->macro_blocks == NULL) {
+ macroblocks->blocks = malloc(sizeof(XvMCBlockArray));
+ macroblocks->macro_blocks = malloc(sizeof(XvMCMacroBlockArray));
+ memset (macroblocks->blocks, 0, sizeof(XvMCBlockArray));
+ memset (macroblocks->macro_blocks, 0, sizeof(XvMCMacroBlockArray));
+#ifdef LOG
+ printf(" macroblocks->blocks %lx ->macro_blocks %lx\n",macroblocks->blocks,macroblocks->macro_blocks);
+#endif
+ }
+
+ if((this->context_id.xid != NULL) &&
+ (width == this->surface_width) &&
+ (height == this->surface_height) &&
+ (format == this->surface_format) &&
+ (flags == this->surface_flags)) {
+
+ // don't need to change context
+#ifdef LOG
+ printf ("video_out_xvmc: didn't change context\n");
+#endif
+ return(&this->context_id);
+
+ } else {
+ if(this->context_id.xid != NULL) {
+
+ // flush any drawing and wait till we are done with the old stuff
+ // blow away the old stuff
+#ifdef LOG
+ printf ("video_out_xvmc: freeing previous context\n");
+ fflush(stdout);
+#endif
+
+ XvMCDestroyBlocks(this->display, macroblocks->blocks);
+ XvMCDestroyMacroBlocks(this->display, macroblocks->macro_blocks);
+
+ for(i = 0; i < this->num_frame_buffers; i++) {
+ XvMCFlushSurface(this->display, &this->frames[i]->surface);
+ XvMCSyncSurface(this->display, &this->frames[i]->surface);
+
+ XvMCDestroySurface(this->display, &this->frames[i]->surface);
+ }
+ XvMCDestroyContext(this->display, &this->context);
+ this->context_id.xid = NULL;
+ }
+
+#ifdef DLOG
+ printf("CreateContext w %d h %d id %x portNum %x\n",width,height,this->surface_type_id,(int)this->xv_port);
+#endif
+
+ // now create a new context
+ result = XvMCCreateContext(this->display, this->xv_port,
+ this->surface_type_id,
+ width, height, XVMC_DIRECT, &this->context);
+
+ if(result != Success) {
+ fprintf(stderr, "set_context: couldn't create XvMCContext\n");
+ macroblocks->xine_mc.xvmc_accel=0;
+ abort();
+ }
+
+ this->context_id.xid = (void *)this->context.context_id;
+
+ for(i = 0; i < this->num_frame_buffers; i++) {
+ result = XvMCCreateSurface(this->display, &this->context,
+ &this->frames[i]->surface);
+ if(result != Success) {
+ XvMCDestroyContext(this->display, &this->context);
+ fprintf(stderr, "set_context: couldn't create XvMCSurfaces\n");
+ this->context_id.xid = NULL;
+ macroblocks->xine_mc.xvmc_accel=0;
+ abort();
+ }
+#ifdef LOG
+ printf (" CreatedSurface %d 0x%lx\n",i,(long)&this->frames[i]->surface);
+#endif
+
+ }
+
+ slices = (slices * width/16);
+
+#ifdef DLOG
+ printf("CreateBlocks slices %d\n",slices);
+#endif
+
+ result = XvMCCreateBlocks(this->display, &this->context, slices * 6,
+ macroblocks->blocks);
+ if(result != Success) {
+ fprintf(stderr, "set_context: ERROR XvMCCreateBlocks failed\n");
+ macroblocks->xine_mc.xvmc_accel=0;
+ abort();
+ }
+ result =XvMCCreateMacroBlocks(this->display, &this->context, slices,
+ macroblocks->macro_blocks);
+ if(result != Success) {
+ fprintf(stderr, "set_context: ERROR XvMCCreateMacroBlocks failed\n");
+ macroblocks->xine_mc.xvmc_accel=0;
+ abort();
+ }
+
+#ifdef LOG
+ printf (" Created bock and macro block arrays\n");
+#endif
+
+ macroblocks->xine_mc.blockbaseptr = macroblocks->blocks->blocks;
+ macroblocks->xine_mc.blockptr = macroblocks->xine_mc.blockbaseptr;
+ macroblocks->num_blocks = 0;
+ macroblocks->macroblockbaseptr = macroblocks->macro_blocks->macro_blocks;
+ macroblocks->macroblockptr = macroblocks->macroblockbaseptr;
+ macroblocks->slices=slices;
+ macroblocks->xine_mc.xvmc_accel=this->acceleration;
+
+ return(&this->context_id);
+ }
+}
+
+int HandleXError (Display *display, XErrorEvent *xevent) {
+
+ char str [1024];
+
+ XGetErrorText (display, xevent->error_code, str, 1024);
+
+ printf ("received X error event: %s\n", str);
+
+ gX11Fail = 1;
+ return 0;
+
+}
+
+static void x11_InstallXErrorHandler (xvmc_driver_t *this)
+{
+ XSetErrorHandler (HandleXError);
+ XFlush (this->display);
+}
+
+static void x11_DeInstallXErrorHandler (xvmc_driver_t *this)
+{
+ XSetErrorHandler (NULL);
+ XFlush (this->display);
+}
+
+static XvImage *create_ximage (xvmc_driver_t *this, XShmSegmentInfo *shminfo,
+ int width, int height, int format) {
+
+ unsigned int xvmc_format;
+ XvImage *image=NULL;
+
+#ifdef LOG
+ printf ("video_out_xvmc: create_ximage\n");
+#endif
+
+ switch (format) {
+ case XINE_IMGFMT_YV12:
+ case XINE_IMGFMT_XVMC:
+ xvmc_format = this->xvmc_format_yv12;
+ break;
+ case XINE_IMGFMT_YUY2:
+ xvmc_format = this->xvmc_format_yuy2;
+ break;
+ default:
+ fprintf (stderr, "create_ximage: unknown format %08x\n",format);
+ abort();
+ }
+
+ /*
+ * plain Xv
+ */
+
+ if (1) {
+
+ char *data;
+
+ switch (format) {
+ case XINE_IMGFMT_YV12:
+ case XINE_IMGFMT_XVMC:
+ data = malloc (width * height * 3/2);
+ break;
+ case XINE_IMGFMT_YUY2:
+ data = malloc (width * height * 2);
+ break;
+ default:
+ fprintf (stderr, "create_ximage: unknown format %08x\n",format);
+ abort();
+ }
+
+ image = XvCreateImage (this->display, this->xv_port,
+ xvmc_format, data, width, height);
+ }
+ return image;
+}
+
+static void dispose_ximage (xvmc_driver_t *this,
+ XShmSegmentInfo *shminfo,
+ XvImage *myimage) {
+
+#ifdef LOG
+ printf ("video_out_xvmc: dispose_ximage\n");
+#endif
+
+ XFree (myimage);
+}
+
+static void xvmc_update_frame_format (vo_driver_t *this_gen,
+ vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height,
+ double ratio, int format, int flags) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+ xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_update_frame_format\n");
+#endif
+
+ if ((frame->width != width)
+ || (frame->height != height)
+ || (frame->format != format)) {
+
+#ifdef LOG
+ printf ("video_out_xvmc: updating frame to %d x %d (ratio=%f, format=%08x)\n",width,height,ratio,format);
+#endif
+ XLockDisplay (this->display);
+
+ /*
+ * (re-) allocate xvimage
+ */
+
+ if (frame->image) {
+ dispose_ximage (this, &frame->shminfo, frame->image);
+ frame->image = NULL;
+ }
+
+ frame->image = create_ximage (this, &frame->shminfo, width, height, format);
+
+ frame->vo_frame.pitches[0] = frame->image->pitches[0];
+ frame->vo_frame.pitches[1] = frame->image->pitches[2];
+ frame->vo_frame.pitches[2] = frame->image->pitches[1];
+ frame->vo_frame.base[0] = frame->image->data + frame->image->offsets[0];
+ frame->vo_frame.base[1] = frame->image->data + frame->image->offsets[2];
+ frame->vo_frame.base[2] = frame->image->data + frame->image->offsets[1];
+
+ frame->width = width;
+ frame->height = height;
+ frame->format = format;
+
+ XUnlockDisplay (this->display);
+ }
+
+ frame->ratio = ratio;
+
+ frame->vo_frame.macroblocks = (xine_macroblocks_t *)&this->macroblocks;
+ if( flags & VO_NEW_SEQUENCE_FLAG ) {
+ xvmc_set_context (this, width, height, ratio, format, flags,
+ frame->vo_frame.macroblocks);
+ }
+ this->macroblocks.num_blocks = 0;
+ this->macroblocks.macroblockptr = this->macroblocks.macroblockbaseptr;
+ this->macroblocks.xine_mc.blockptr = this->macroblocks.xine_mc.blockbaseptr;
+}
+
+static void xvmc_clean_output_area (xvmc_driver_t *this) {
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_clean_output_area\n");
+#endif
+
+ XLockDisplay (this->display);
+
+ XSetForeground (this->display, this->gc, this->black.pixel);
+
+ XFillRectangle(this->display, this->drawable, this->gc,
+ this->sc.gui_x, this->sc.gui_y, this->sc.gui_width, this->sc.gui_height);
+
+ if (this->use_colorkey) {
+ XSetForeground (this->display, this->gc, this->colorkey);
+ XFillRectangle (this->display, this->drawable, this->gc,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height);
+ }
+
+ XUnlockDisplay (this->display);
+}
+
+/*
+ * convert delivered height/width to ideal width/height
+ * taking into account aspect ratio and zoom factor
+ */
+
+static void xvmc_compute_ideal_size (xvmc_driver_t *this) {
+
+ vo_scale_compute_ideal_size( &this->sc );
+}
+
+
+/*
+ * make ideal width/height "fit" into the gui
+ */
+
+static void xvmc_compute_output_size (xvmc_driver_t *this) {
+
+ vo_scale_compute_output_size( &this->sc );
+
+}
+
+static void xvmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) {
+
+ xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_overlay_blend\n");
+#endif
+
+ /* Alpha Blend here
+ * As XV drivers improve to support Hardware overlay, we will change this function.
+ */
+
+ if (overlay->rle) {
+ if (frame->format == XINE_IMGFMT_YV12)
+ blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches);
+ else
+ blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]);
+ }
+
+}
+
+static void xvmc_add_recent_frame (xvmc_driver_t *this, xvmc_frame_t *frame) {
+ int i;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_add_recent_frame\n");
+#endif
+
+ i = VO_NUM_RECENT_FRAMES-1;
+ if( this->recent_frames[i] )
+ this->recent_frames[i]->vo_frame.free
+ (&this->recent_frames[i]->vo_frame);
+
+ for( ; i ; i-- )
+ this->recent_frames[i] = this->recent_frames[i-1];
+
+ this->recent_frames[0] = frame;
+}
+
+/* currently not used - we could have a method to call this from video loop */
+#if 0
+static void xvmc_flush_recent_frames (xvmc_driver_t *this) {
+
+ int i;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_flush_recent_frames\n");
+#endif
+
+ for( i=0; i < VO_NUM_RECENT_FRAMES; i++ )
+ {
+ if( this->recent_frames[i] )
+ this->recent_frames[i]->vo_frame.free
+ (&this->recent_frames[i]->vo_frame);
+ this->recent_frames[i] = NULL;
+ }
+}
+#endif
+
+static int xvmc_redraw_needed (vo_driver_t *this_gen) {
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+ int ret = 0;
+
+ if( this->cur_frame ) {
+
+ this->sc.delivered_height = this->cur_frame->height;
+ this->sc.delivered_width = this->cur_frame->width;
+ this->sc.delivered_ratio = this->cur_frame->ratio;
+
+ xvmc_compute_ideal_size(this);
+
+ if( vo_scale_redraw_needed( &this->sc ) ) {
+
+ xvmc_compute_output_size (this);
+
+ xvmc_clean_output_area (this);
+
+ ret = 1;
+ }
+ }
+ else
+ ret = 1;
+
+ return ret;
+}
+
+static void xvmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+ xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen;
+ int status;
+
+#ifdef LOG1
+ printf ("video_out_xvmc: xvmc_display_frame %d %x\n",frame_gen->id,frame_gen);
+#endif
+
+ if (this->expecting_event) {
+
+ frame->vo_frame.free (&frame->vo_frame);
+ this->expecting_event--;
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_display_frame... not displayed, waiting for completion event\n");
+#endif
+ } else {
+
+ /*
+ * queue frames (deinterlacing)
+ * free old frames
+ */
+
+ xvmc_add_recent_frame (this, frame); /* deinterlacing */
+
+ this->cur_frame = frame;
+
+ /*
+ * let's see if this frame is different in size / aspect
+ * ratio from the previous one
+ */
+
+ if ( (frame->width != this->sc.delivered_width)
+ || (frame->height != this->sc.delivered_height)
+ || (frame->ratio != this->sc.delivered_ratio) ) {
+#ifdef LOG
+ printf("video_out_xvmc: frame format changed\n");
+#endif
+
+ // this->delivered_width = frame->width;
+ // this->delivered_height = frame->height;
+ // this->delivered_ratio = frame->ratio;
+ // this->delivered_duration = frame->vo_frame.duration;
+
+ //xvmc_compute_ideal_size (this);
+
+ //this->gui_width = 0; /* trigger re-calc of output size */
+ this->sc.force_redraw = 1; /* trigger re-calc of output size */
+ }
+
+ /*
+ * tell gui that we are about to display a frame,
+ * ask for offset and output size
+ */
+ xvmc_redraw_needed (this_gen);
+
+ XLockDisplay (this->display);
+
+ XvMCGetSurfaceStatus(this->display, &this->cur_frame->surface, &status);
+
+ if(status & XVMC_RENDERING) {
+ printf("--------- current frame is still being rendered %x --------\n",status);
+ fflush(stdout);
+ XvMCSyncSurface(this->display, &this->cur_frame->surface);
+ }
+
+ if (this->deinterlace_enabled &&
+ (this->deinterlace_method == DEINTERLACE_ONEFIELD)) {
+ XvMCPutSurface(this->display, &this->cur_frame->surface,
+ this->drawable,
+ this->sc.displayed_xoffset, this->sc.displayed_yoffset,
+ this->sc.displayed_width, this->sc.displayed_height,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height,
+ XVMC_TOP_FIELD);
+ } else { // WEAVE
+ XvMCPutSurface(this->display, &this->cur_frame->surface,
+ this->drawable,
+ this->sc.displayed_xoffset, this->sc.displayed_yoffset,
+ this->sc.displayed_width, this->sc.displayed_height,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height,
+ XVMC_FRAME_PICTURE);
+ }
+
+ // XFlush(this->display);
+
+ XUnlockDisplay (this->display);
+
+ }
+ /*
+ printf ("video_out_xvmc: xvmc_display_frame... done\n");
+ */
+}
+
+static int xvmc_get_property (vo_driver_t *this_gen, int property) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_get_property\n");
+#endif
+
+ return this->props[property].value;
+}
+
+static void xvmc_property_callback (void *property_gen, xine_cfg_entry_t *entry) {
+
+ xvmc_property_t *property = (xvmc_property_t *) property_gen;
+ xvmc_driver_t *this = property->this;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_property_callback\n");
+#endif
+
+ XvSetPortAttribute (this->display, this->xv_port,
+ property->atom, entry->num_value);
+
+}
+
+static int xvmc_set_property (vo_driver_t *this_gen,
+ int property, int value) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_set_property %d value %d\n",property,value);
+#endif
+
+ if (this->props[property].atom != None) {
+ /* value is out of bound */
+ if((value < this->props[property].min) || (value > this->props[property].max))
+ value = (this->props[property].min + this->props[property].max) >> 1;
+
+ XvSetPortAttribute (this->display, this->xv_port,
+ this->props[property].atom, value);
+ XvGetPortAttribute (this->display, this->xv_port,
+ this->props[property].atom,
+ &this->props[property].value);
+
+ if (this->props[property].entry)
+ this->props[property].entry->num_value = this->props[property].value;
+
+ return this->props[property].value;
+ } else {
+ switch (property) {
+ case VO_PROP_INTERLACED:
+
+ this->props[property].value = value;
+ printf("video_out_xvmc: VO_PROP_INTERLACED(%d)\n",
+ this->props[property].value);
+ this->deinterlace_enabled = value;
+ if (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) {
+ xvmc_compute_ideal_size (this);
+ }
+ break;
+ case VO_PROP_ASPECT_RATIO:
+
+ if (value>=XINE_VO_ASPECT_NUM_RATIOS)
+ value = XINE_VO_ASPECT_AUTO;
+
+ this->props[property].value = value;
+ printf("video_out_xvmc: VO_PROP_ASPECT_RATIO(%d)\n",
+ this->props[property].value);
+
+ xvmc_compute_ideal_size (this);
+ xvmc_compute_output_size (this);
+ xvmc_clean_output_area (this);
+
+ break;
+ case VO_PROP_ZOOM_X:
+
+ if ((value >= VO_ZOOM_MIN) && (value <= VO_ZOOM_MAX)) {
+ this->props[property].value = value;
+ printf ("video_out_xv: VO_PROP_ZOOM_X = %d\n",
+ this->props[property].value);
+
+ this->sc.zoom_factor_x = (double)value / (double)VO_ZOOM_STEP;
+
+ xvmc_compute_ideal_size (this);
+
+ this->sc.force_redraw = 1; /* trigger re-calc of output size */
+ }
+ break;
+ case VO_PROP_ZOOM_Y:
+
+ if ((value >= VO_ZOOM_MIN) && (value <= VO_ZOOM_MAX)) {
+ this->props[property].value = value;
+ printf ("video_out_xv: VO_PROP_ZOOM_Y = %d\n",
+ this->props[property].value);
+
+ this->sc.zoom_factor_y = (double)value / (double)VO_ZOOM_STEP;
+
+ xvmc_compute_ideal_size (this);
+
+ this->sc.force_redraw = 1; /* trigger re-calc of output size */
+ }
+ break;
+ }
+ }
+
+ return value;
+}
+
+static void xvmc_get_property_min_max (vo_driver_t *this_gen,
+ int property, int *min, int *max) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_get_property_min_max\n");
+#endif
+
+ *min = this->props[property].min;
+ *max = this->props[property].max;
+}
+
+static int xvmc_gui_data_exchange (vo_driver_t *this_gen,
+ int data_type, void *data) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_gui_data_exchange\n");
+#endif
+
+ switch (data_type) {
+ case XINE_GUI_SEND_COMPLETION_EVENT: {
+
+ XShmCompletionEvent *cev = (XShmCompletionEvent *) data;
+
+ if (cev->drawable == this->drawable) {
+ this->expecting_event = 0;
+
+ }
+
+ }
+ break;
+
+ case XINE_GUI_SEND_EXPOSE_EVENT: {
+
+ /* XExposeEvent * xev = (XExposeEvent *) data; */
+
+ /* FIXME : take care of completion events */
+
+ // printf ("video_out_xvmc: XINE_GUI_SEND_EXPOSE_EVENT\n");
+
+ if (this->cur_frame) {
+ int i;
+
+ XLockDisplay (this->display);
+
+ // XvPutImage(this->display, this->xv_port,
+ // this->drawable, this->gc, this->cur_frame->image,
+ // this->sc.displayed_xoffset, this->sc.displayed_yoffset,
+ // this->sc.displayed_width, this->sc.displayed_height,
+ // this->sc.output_xoffset, this->sc.output_yoffset,
+ // this->sc.output_width, this->sc.output_height);
+
+ XSetForeground (this->display, this->gc, this->black.pixel);
+
+ for( i = 0; i < 4; i++ ) {
+ if( this->sc.border[i].w && this->sc.border[i].h )
+ XFillRectangle(this->display, this->drawable, this->gc,
+ this->sc.border[i].x, this->sc.border[i].y,
+ this->sc.border[i].w, this->sc.border[i].h);
+ }
+
+ if (this->use_colorkey) {
+ XSetForeground (this->display, this->gc, this->colorkey);
+ XFillRectangle (this->display, this->drawable, this->gc,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height);
+ }
+
+ XvMCPutSurface(this->display, &this->cur_frame->surface,
+ this->drawable,
+ this->sc.displayed_xoffset, this->sc.displayed_yoffset,
+ this->sc.displayed_width, this->sc.displayed_height,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height,
+ XVMC_FRAME_PICTURE);
+
+ XFlush(this->display);
+
+ XUnlockDisplay (this->display);
+ }
+ }
+ break;
+
+ case XINE_GUI_SEND_DRAWABLE_CHANGED:
+ this->drawable = (Drawable) data;
+ this->gc = XCreateGC (this->display, this->drawable, 0, NULL);
+ break;
+
+ case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO:
+ {
+ int x1, y1, x2, y2;
+ x11_rectangle_t *rect = data;
+
+// xvmc_translate_gui2video(this, rect->x, rect->y,
+// &x1, &y1);
+// xvmc_translate_gui2video(this, rect->x + rect->w, rect->y + rect->h,
+// &x2, &y2);
+
+ vo_scale_translate_gui2video(&this->sc, rect->x, rect->y,
+ &x1, &y1);
+ vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h,
+ &x2, &y2);
+
+ rect->x = x1;
+ rect->y = y1;
+ rect->w = x2-x1;
+ rect->h = y2-y1;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static void xvmc_dispose (vo_driver_t *this_gen) {
+
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+ int i;
+
+#ifdef LOG
+ printf ("video_out_xvmc: xvmc_dispose\n");
+#endif
+
+ if (this->deinterlace_frame.image) {
+ dispose_ximage (this, &this->deinterlace_frame.shminfo,
+ this->deinterlace_frame.image);
+ this->deinterlace_frame.image = NULL;
+ }
+
+ if(this->context_id.xid) {
+ for(i = 0; i < this->num_frame_buffers; i++) {
+ // if(useOverlay) /* only one is displaying but I don't want to keep track*/
+ XvMCHideSurface(this->display, &this->frames[i]->surface);
+ XvMCDestroySurface(this->display, &this->frames[i]->surface);
+ }
+ // XvMCDestroyBlocks(this->display, &macroblocks->blocks);
+ // XvMCDestroyMacroBlocks(this->display, &macroblocks->macro_blocks);
+ XvMCDestroyContext(this->display, &this->context);
+ }
+
+ XLockDisplay (this->display);
+ if(XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) {
+ printf ("video_out_xvmc: xvmc_dispose: XvUngrabPort() failed.\n");
+ }
+ XUnlockDisplay (this->display);
+
+ for( i=0; i < VO_NUM_RECENT_FRAMES; i++ )
+ {
+ if( this->recent_frames[i] )
+ this->recent_frames[i]->vo_frame.dispose
+ (&this->recent_frames[i]->vo_frame);
+ this->recent_frames[i] = NULL;
+ }
+
+ free (this);
+}
+
+static void xvmc_check_capability (xvmc_driver_t *this,
+ uint32_t capability,
+ int property, XvAttribute attr,
+ int base_id, char *str_prop,
+ char *config_name,
+ char *config_desc) {
+
+ int int_default;
+ cfg_entry_t *entry;
+
+ this->capabilities |= capability;
+
+ /*
+ * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing.
+ */
+ if (VO_CAP_COLORKEY && (attr.max_value == ~0))
+ attr.max_value = 2147483615;
+
+ this->props[property].min = attr.min_value;
+ this->props[property].max = attr.max_value;
+ this->props[property].atom = XInternAtom (this->display, str_prop, False);
+
+ XvGetPortAttribute (this->display, this->xv_port,
+ this->props[property].atom, &int_default);
+
+ printf ("video_out_xvmc: port attribute %s (%d) value is %d\n",
+ str_prop, property, int_default);
+
+ if (config_name) {
+ /* is this a boolean property ? */
+ if ((attr.min_value == 0) && (attr.max_value == 1)) {
+ this->config->register_bool (this->config, config_name, int_default,
+ config_desc,
+ NULL, 10, xvmc_property_callback, &this->props[property]);
+
+ } else {
+ this->config->register_range (this->config, config_name, int_default,
+ this->props[property].min, this->props[property].max,
+ config_desc,
+ NULL, 10, xvmc_property_callback, &this->props[property]);
+ }
+
+ entry = this->config->lookup_entry (this->config, config_name);
+
+ this->props[property].entry = entry;
+
+ xvmc_set_property (&this->vo_driver, property, entry->num_value);
+
+ if (capability == VO_CAP_COLORKEY) {
+ this->use_colorkey = 1;
+ this->colorkey = entry->num_value;
+ }
+ } else
+ this->props[property].value = int_default;
+}
+
+static void xvmc_update_deinterlace(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+
+ //#ifdef LOG
+ printf ("video_out_xvmc: xvmc_update_deinterlace method = %d\n",entry->num_value);
+ //#endif
+
+ this->deinterlace_method = entry->num_value;
+}
+
+static void xvmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xvmc_driver_t *this = (xvmc_driver_t *) this_gen;
+ Atom atom;
+ int xvmc_double_buffer;
+
+ xvmc_double_buffer = entry->num_value;
+
+ atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False);
+
+ XvSetPortAttribute (this->display, this->xv_port, atom, xvmc_double_buffer);
+ printf("video_out_xvmc: double buffering mode = %d\n",xvmc_double_buffer);
+}
+
+static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) {
+
+ xvmc_class_t *class = (xvmc_class_t *) class_gen;
+ config_values_t *config = class->config;
+ xvmc_driver_t *this = NULL;
+ Display *display = NULL;
+ unsigned int i, formats;
+ XvPortID xv_port = class->xv_port;
+ XvAttribute *attr;
+ XvImageFormatValues *fo;
+ int nattr;
+ x11_visual_t *visual = (x11_visual_t *) visual_gen;
+ XColor dummy;
+ // XvImage *myimage;
+
+#ifdef LOG
+ printf ("video_out_xvmc: open_plugin\n");
+#endif
+
+ display = visual->display;
+
+ // TODO ???
+ this = malloc (sizeof (xvmc_driver_t));
+
+ if (!this) {
+ printf ("video_out_xvmc: malloc failed\n");
+ return NULL;
+ }
+
+ memset (this, 0, sizeof(xvmc_driver_t));
+
+ this->display = visual->display;
+ this->overlay = NULL;
+ this->screen = visual->screen;
+ this->xv_port = class->xv_port;
+ this->config = config;
+
+ vo_scale_init (&this->sc, 1, 0, config );
+
+ this->sc.frame_output_cb = visual->frame_output_cb;
+ this->sc.user_data = visual->user_data;
+
+ this->drawable = visual->d;
+ this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
+ this->capabilities = VO_CAP_XVMC_MOCOMP;
+ this->expecting_event = 0;
+
+ this->surface_type_id = class->surface_type_id;
+ this->max_surface_width = class->max_surface_width;
+ this->max_surface_height = class->max_surface_height;
+ this->context_id.xid = NULL;
+ this->num_frame_buffers = 0;
+ this->acceleration = class->acceleration;
+
+ // TODO CLEAN UP THIS
+ this->user_data = visual->user_data;
+
+ this->deinterlace_method = 0;
+ this->deinterlace_frame.image = NULL;
+ this->use_colorkey = 0;
+ this->colorkey = 0;
+
+ XAllocNamedColor(this->display,
+ DefaultColormap(this->display, this->screen),
+ "black", &this->black, &dummy);
+
+ this->vo_driver.get_capabilities = xvmc_get_capabilities;
+ this->vo_driver.alloc_frame = xvmc_alloc_frame;
+ this->vo_driver.update_frame_format = xvmc_update_frame_format;
+ this->vo_driver.overlay_blend = xvmc_overlay_blend;
+ this->vo_driver.display_frame = xvmc_display_frame;
+ this->vo_driver.get_property = xvmc_get_property;
+ this->vo_driver.set_property = xvmc_set_property;
+ this->vo_driver.get_property_min_max = xvmc_get_property_min_max;
+ this->vo_driver.gui_data_exchange = xvmc_gui_data_exchange;
+ this->vo_driver.dispose = xvmc_dispose;
+ this->vo_driver.redraw_needed = xvmc_redraw_needed;
+
+ /*
+ * init properties
+ */
+
+ for (i=0; i<VO_NUM_PROPERTIES; i++) {
+ this->props[i].value = 0;
+ this->props[i].min = 0;
+ this->props[i].max = 0;
+ this->props[i].atom = None;
+ this->props[i].entry = NULL;
+ this->props[i].this = this;
+ }
+
+ this->props[VO_PROP_INTERLACED].value = 0;
+ this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO;
+ this->props[VO_PROP_ZOOM_X].value = 100;
+ this->props[VO_PROP_ZOOM_Y].value = 100;
+ this->props[VO_PROP_MAX_NUM_FRAMES].value = MAX_NUM_FRAMES;
+
+ /*
+ * check this adaptor's capabilities
+ */
+
+ if(this->acceleration&XINE_VO_IDCT_ACCEL)
+ this->capabilities |= VO_CAP_XVMC_IDCT;
+
+ attr = XvQueryPortAttributes(display, xv_port, &nattr);
+ if(attr && nattr) {
+ int k;
+
+ for(k = 0; k < nattr; k++) {
+ if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) {
+ if(!strcmp(attr[k].name, "XV_HUE")) {
+ xvmc_check_capability (this, VO_CAP_HUE,
+ VO_PROP_HUE, attr[k],
+ class->adaptor_info[class->adaptor_num].base_id, "XV_HUE",
+ NULL, NULL);
+
+ } else if(!strcmp(attr[k].name, "XV_SATURATION")) {
+ xvmc_check_capability (this, VO_CAP_SATURATION,
+ VO_PROP_SATURATION, attr[k],
+ class->adaptor_info[class->adaptor_num].base_id, "XV_SATURATION",
+ NULL, NULL);
+
+ } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) {
+ xvmc_check_capability (this, VO_CAP_BRIGHTNESS,
+ VO_PROP_BRIGHTNESS, attr[k],
+ class->adaptor_info[class->adaptor_num].base_id, "XV_BRIGHTNESS",
+ NULL, NULL);
+
+ } else if(!strcmp(attr[k].name, "XV_CONTRAST")) {
+ xvmc_check_capability (this, VO_CAP_CONTRAST,
+ VO_PROP_CONTRAST, attr[k],
+ class->adaptor_info[class->adaptor_num].base_id, "XV_CONTRAST",
+ NULL, NULL);
+
+ } else if(!strcmp(attr[k].name, "XV_COLORKEY")) {
+ xvmc_check_capability (this, VO_CAP_COLORKEY,
+ VO_PROP_COLORKEY, attr[k],
+ class->adaptor_info[class->adaptor_num].base_id, "XV_COLORKEY",
+ "video.xv_colorkey",
+ _("Colorkey used for Xv video overlay"));
+
+ } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) {
+ xvmc_check_capability (this, VO_CAP_AUTOPAINT_COLORKEY,
+ VO_PROP_AUTOPAINT_COLORKEY, attr[k],
+ class->adaptor_info[class->adaptor_num].base_id, "XV_AUTOPAINT_COLORKEY",
+ NULL, NULL);
+
+ } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) {
+ int xvmc_double_buffer;
+ xvmc_double_buffer = config->register_bool (config, "video.XV_DOUBLE_BUFFER", 1,
+ _("double buffer to sync video to the retrace"),
+ NULL, 10, xvmc_update_XV_DOUBLE_BUFFER, this);
+ config->update_num(config,"video.XV_DOUBLE_BUFFER",xvmc_double_buffer);
+ }
+ }
+ }
+ XFree(attr);
+ } else {
+ printf("video_out_xvmc: no port attributes defined.\n");
+ }
+
+
+ /*
+ * check supported image formats
+ */
+
+ fo = XvListImageFormats(display, this->xv_port, (int*)&formats);
+
+ this->xvmc_format_yv12 = 0;
+ this->xvmc_format_yuy2 = 0;
+
+ for(i = 0; i < formats; i++) {
+#ifdef LOG
+ printf ("video_out_xvmc: XvMC image format: 0x%x (%4.4s) %s\n",
+ fo[i].id, (char*)&fo[i].id,
+ (fo[i].format == XvPacked) ? "packed" : "planar");
+#endif
+ if (fo[i].id == XINE_IMGFMT_YV12) {
+ this->xvmc_format_yv12 = fo[i].id;
+ this->capabilities |= VO_CAP_YV12;
+ printf("video_out_xvmc: this adaptor supports the yv12 format.\n");
+ } else if (fo[i].id == XINE_IMGFMT_YUY2) {
+ this->xvmc_format_yuy2 = fo[i].id;
+ this->capabilities |= VO_CAP_YUY2;
+ printf("video_out_xvmc: this adaptor supports the yuy2 format.\n");
+ }
+ }
+
+ /*
+ * try to create a shared image
+ * to find out if MIT shm really works, using supported format
+ */
+ // myimage = create_ximage (this, &myshminfo, 100, 100,
+ // (this->xvmc_format_yv12 != 0) ? XINE_IMGFMT_YV12 : IMGFMT_YUY2);
+ // dispose_ximage (this, &myshminfo, myimage);
+
+ this->deinterlace_method = config->register_enum (config, "video.deinterlace_method", 4,
+ deinterlace_methods,
+ _("Software deinterlace method (Key I toggles deinterlacer on/off)"),
+ NULL, 10, xvmc_update_deinterlace, this);
+ this->deinterlace_enabled = 1; // default is enabled
+ printf("video_out_xvmc: deinterlace_methods %d ",this->deinterlace_method);
+ switch(this->deinterlace_method) {
+ case DEINTERLACE_NONE: printf("NONE\n"); break;
+ case DEINTERLACE_BOB: printf("BOB\n"); break;
+ case DEINTERLACE_WEAVE: printf("WEAVE\n"); break;
+ case DEINTERLACE_GREEDY: printf("GREEDY\n"); break;
+ case DEINTERLACE_ONEFIELD: printf("ONEFIELD\n"); break;
+ case DEINTERLACE_ONEFIELDXV: printf("ONEFIELDXV\n"); break;
+ case DEINTERLACE_LINEARBLEND: printf("LINEARBLEND\n"); break;
+ }
+ printf("video_out_xvmc: initialization of plugin successful\n");
+
+ return &this->vo_driver;
+}
+
+/*
+ * class functions
+ */
+
+static char* get_identifier (video_driver_class_t *this_gen) {
+ return "XvMC";
+}
+
+static char* get_description (video_driver_class_t *this_gen) {
+ return _("xine video output plugin using the XvMC X video extension");
+}
+
+static void dispose_class (video_driver_class_t *this_gen) {
+
+ xvmc_class_t *this = (xvmc_class_t *) this_gen;
+
+ XvFreeAdaptorInfo (this->adaptor_info);
+
+ free (this);
+}
+
+static void *init_class (xine_t *xine, void *visual_gen) {
+
+ x11_visual_t *visual = (x11_visual_t *) visual_gen;
+ xvmc_class_t *this;
+ Display *display = NULL;
+ unsigned int adaptors, j = 0;
+ unsigned int ver,rel,req,ev,err;
+ XvPortID xv_port;
+ XvAdaptorInfo *adaptor_info;
+ unsigned int adaptor_num;
+
+ /* XvMC */
+ int IDCTaccel = 0;
+ int useOverlay = 0;
+ int unsignedIntra = 0;
+ unsigned int surface_num, types;
+ unsigned int max_width=0, max_height=0;
+ XvMCSurfaceInfo *surfaceInfo;
+ int surface_type = 0;
+
+
+ display = visual->display;
+
+ /*
+ * check for Xv and XvMC video support
+ */
+
+ printf ("video_out_xvmc: XvMC init_class\n");
+
+ if (Success != XvQueryExtension(display,&ver,&rel,&req,&ev,&err)) {
+ printf ("video_out_xvmc: Xv extension not present.\n");
+ return NULL;
+ }
+
+ if(!XvMCQueryExtension(display, &ev, &err)) {
+ printf ("video_out_xvmc: XvMC extension not present.\n");
+ return 0;
+ }
+
+ /*
+ * check adaptors, search for one that supports (at least) yuv12
+ */
+
+ if(Success != XvQueryAdaptors(display,DefaultRootWindow(display),
+ &adaptors,&adaptor_info)) {
+ printf ("video_out_xvmc: XvQueryAdaptors failed.\n");
+ return 0;
+ }
+
+ xv_port = 0;
+
+ for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) {
+ printf ("video_out_xvmc: checking adaptor %d\n",adaptor_num);
+ if (adaptor_info[adaptor_num].type & XvImageMask) {
+ surfaceInfo = XvMCListSurfaceTypes(display, adaptor_info[adaptor_num].base_id,
+ &types);
+ if(surfaceInfo) {
+ for(surface_num = 0; surface_num < types; surface_num++) {
+ if((surfaceInfo[surface_num].chroma_format == XVMC_CHROMA_FORMAT_420) &&
+ (surfaceInfo[surface_num].mc_type == (XVMC_IDCT | XVMC_MPEG_2))) {
+ max_width = surfaceInfo[surface_num].max_width;
+ max_height = surfaceInfo[surface_num].max_height;
+ for(j = 0; j < adaptor_info[adaptor_num].num_ports; j++) {
+ /* try to grab a port */
+ if(Success == XvGrabPort(display, adaptor_info[adaptor_num].base_id + j,
+ CurrentTime))
+ {
+ xv_port = adaptor_info[adaptor_num].base_id + j;
+ surface_type = surfaceInfo[j].surface_type_id;
+ break;
+ }
+ }
+ if(xv_port) break;
+ }
+ }
+ if(!xv_port) { // try for just XVMC_MOCOMP
+ printf ("video_out_xvmc: didn't find XVMC_IDCT acceleration trying for MC\n");
+ for(surface_num = 0; surface_num < types; surface_num++) {
+ if((surfaceInfo[surface_num].chroma_format == XVMC_CHROMA_FORMAT_420) &&
+ ((surfaceInfo[surface_num].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)))) {
+ printf ("video_out_xvmc: Found XVMC_MOCOMP\n");
+ max_width = surfaceInfo[surface_num].max_width;
+ max_height = surfaceInfo[surface_num].max_height;
+ for(j = 0; j < adaptor_info[adaptor_num].num_ports; j++) {
+ /* try to grab a port */
+ if(Success == XvGrabPort(display, adaptor_info[adaptor_num].base_id + j,
+ CurrentTime))
+ {
+ xv_port = adaptor_info[adaptor_num].base_id + j;
+ surface_type = surfaceInfo[j].surface_type_id;
+ break;
+ }
+ }
+ if(xv_port) break;
+ }
+ }
+ }
+ if(xv_port) {
+ printf ("video_out_xvmc: port %ld surface %d\n",xv_port,j);
+ if(surfaceInfo[j].flags & XVMC_OVERLAID_SURFACE)
+ useOverlay = 1;
+ if(surfaceInfo[j].flags & XVMC_INTRA_UNSIGNED)
+ unsignedIntra = 1;
+ if(surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2))
+ IDCTaccel = XINE_VO_IDCT_ACCEL + XINE_VO_MOTION_ACCEL;
+ else if(surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) {
+ IDCTaccel = XINE_VO_MOTION_ACCEL;
+ if(!unsignedIntra)
+ IDCTaccel |= XINE_VO_SIGNED_INTRA;
+ }
+ else
+ IDCTaccel = 0;
+ printf ("video_out_xvmc: IDCTaccel %02x\n",IDCTaccel);
+ break;
+ }
+ XFree(surfaceInfo);
+ }
+ }
+ } // outer for adaptor_num loop
+ if (!xv_port) {
+ printf ("video_out_xvmc: Xv extension is present but "
+ "I couldn't find a usable yuv12 port.\n");
+ printf (" Looks like your graphics hardware "
+ "driver doesn't support Xv?!\n");
+ /* XvFreeAdaptorInfo (adaptor_info); this crashed on me (gb)*/
+ return NULL;
+ } else {
+ printf ("video_out_xvmc: using Xv port %ld from adaptor %s\n"
+ " for hardware colorspace conversion and scaling\n", xv_port,
+ adaptor_info[adaptor_num].name);
+
+ if(IDCTaccel&XINE_VO_IDCT_ACCEL)
+ printf (" idct and motion compensation acceleration \n");
+ else if (IDCTaccel&XINE_VO_MOTION_ACCEL)
+ printf (" motion compensation acceleration only\n");
+ else
+ printf (" no XvMC support \n");
+ printf (" With Overlay = %d; UnsignedIntra = %d.\n", useOverlay,
+ unsignedIntra);
+ }
+
+ this = (xvmc_class_t *) malloc (sizeof (xvmc_class_t));
+
+ if (!this) {
+ printf ("video_out_xvmc: malloc failed\n");
+ return NULL;
+ }
+
+ this->driver_class.open_plugin = open_plugin;
+ this->driver_class.get_identifier = get_identifier;
+ this->driver_class.get_description = get_description;
+ this->driver_class.dispose = dispose_class;
+
+ this->config = xine->config;
+ this->xv_port = xv_port;
+ this->adaptor_info = adaptor_info;
+ this->adaptor_num = adaptor_num;
+ this->surface_type_id = surface_type;
+ this->max_surface_width = max_width;
+ this->max_surface_height = max_height;
+ this->acceleration = IDCTaccel;
+
+ printf("video_out_xvmc: init_class done\n");
+ return this;
+}
+
+static vo_info_t vo_info_xvmc = {
+ /* priority must be low until it supports displaying non-accelerated stuff */
+ 0, /* priority */
+ XINE_VISUAL_TYPE_X11 /* visual type */
+};
+
+/*
+ * exported plugin catalog entry
+ */
+
+plugin_info_t xine_plugin_info[] = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_VIDEO_OUT, 17, "xvmc", XINE_VERSION_CODE, &vo_info_xvmc, init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
+
+#endif
diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c
index a57f9748f..1b1f70308 100644
--- a/src/xine-engine/post.c
+++ b/src/xine-engine/post.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: post.c,v 1.14 2003/08/15 14:38:04 mroi Exp $
+ * $Id: post.c,v 1.15 2003/10/06 21:52:44 miguelfreitas Exp $
*/
/*
@@ -91,7 +91,6 @@ static int post_video_set_property(xine_video_port_t *port_gen, int property, in
return port->original_port->set_property(port->original_port, property, value);
}
-
post_video_port_t *post_intercept_video_port(post_plugin_t *post, xine_video_port_t *original) {
post_video_port_t *post_port = (post_video_port_t *)malloc(sizeof(post_video_port_t));
@@ -158,6 +157,33 @@ static void post_frame_dispose(vo_frame_t *vo_img) {
vo_img->dispose(vo_img);
}
+static void post_frame_proc_macro_block(int x,
+ int y,
+ int mb_type,
+ int motion_type,
+ int (*mv_field_sel)[2],
+ int *dmvector,
+ int cbp,
+ int dct_type,
+ vo_frame_t *current_frame,
+ vo_frame_t *forward_ref_frame,
+ vo_frame_t *backward_ref_frame,
+ int picture_structure,
+ int second_field,
+ int (*f_mot_pmv)[2],
+ int (*b_mot_pmv)[2]) {
+ post_video_port_t *port = (post_video_port_t *)current_frame->port;
+ post_restore_video_frame(current_frame, port);
+ post_restore_video_frame(forward_ref_frame, port);
+ post_restore_video_frame(backward_ref_frame, port);
+ current_frame->proc_macro_block(x, y, mb_type, motion_type, mv_field_sel,
+ dmvector, cbp, dct_type, current_frame,
+ forward_ref_frame, backward_ref_frame,
+ picture_structure, second_field,
+ f_mot_pmv, b_mot_pmv);
+}
+
+
void post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) {
port->original_frame.port = frame->port;
@@ -167,6 +193,7 @@ void post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) {
port->original_frame.draw = frame->draw;
port->original_frame.lock = frame->lock;
port->original_frame.dispose = frame->dispose;
+ port->original_frame.proc_macro_block = frame->proc_macro_block;
frame->port = &port->port;
frame->free = post_frame_free;
@@ -175,6 +202,7 @@ void post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) {
frame->draw = post_frame_draw;
frame->lock = post_frame_lock;
frame->dispose = post_frame_dispose;
+ frame->proc_macro_block = post_frame_proc_macro_block;
}
void post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port) {
@@ -185,6 +213,7 @@ void post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port) {
frame->draw = port->original_frame.draw;
frame->lock = port->original_frame.lock;
frame->dispose = port->original_frame.dispose;
+ frame->proc_macro_block = port->original_frame.proc_macro_block;
}
diff --git a/src/xine-engine/post.h b/src/xine-engine/post.h
index e29f12cdd..8cd658e7a 100644
--- a/src/xine-engine/post.h
+++ b/src/xine-engine/post.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: post.h,v 1.11 2003/08/15 14:38:04 mroi Exp $
+ * $Id: post.h,v 1.12 2003/10/06 21:52:45 miguelfreitas Exp $
*
* post plugin definitions
*
@@ -38,7 +38,7 @@
# include <xine/xineutils.h>
#endif
-#define POST_PLUGIN_IFACE_VERSION 4
+#define POST_PLUGIN_IFACE_VERSION 5
typedef struct post_class_s post_class_t;
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 62dda64be..5c8b12c82 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.171 2003/09/13 16:15:38 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.172 2003/10/06 21:52:45 miguelfreitas Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -298,6 +298,7 @@ static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen,
img->progressive_frame = 0;
img->repeat_first_field = 0;
img->top_field_first = 1;
+ img->macroblocks = NULL;
extra_info_reset ( img->extra_info );
/* let driver ensure this image has the right format */
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 957b8aef7..c4cdb2d03 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.h,v 1.96 2003/08/15 14:35:09 mroi Exp $
+ * $Id: video_out.h,v 1.97 2003/10/06 21:52:45 miguelfreitas Exp $
*
*
* xine version of video_out.h
@@ -70,6 +70,13 @@ typedef struct extra_info_s extra_info_t;
* adaption of the post plugin decoration layer. Be sure to look into
* src/xine-engine/post.[ch].
*/
+
+typedef struct xine_macroblock_s {
+ short *blockptr; // pointer to current dct block
+ short *blockbaseptr; // pointer to base of dct block array in blocks
+ short xvmc_accel; // type of acceleration supported
+} xine_macroblocks_t;
+
struct vo_frame_s {
/*
* member functions
@@ -97,6 +104,23 @@ struct vo_frame_s {
/* free memory/resources for this frame */
void (*dispose) (vo_frame_t *vo_img);
+
+ /* XvMC routine for rendering macroblocks */
+ void (*proc_macro_block)(int x,
+ int y,
+ int mb_type,
+ int motion_type,
+ int (*mv_field_sel)[2],
+ int *dmvector,
+ int cbp,
+ int dct_type,
+ vo_frame_t *current_frame,
+ vo_frame_t *forward_ref_frame,
+ vo_frame_t *backward_ref_frame,
+ int picture_structure,
+ int second_field,
+ int (*f_mot_pmv)[2],
+ int (*b_mot_pmv)[2]);
/*
* public variables to decoders and vo drivers
@@ -119,6 +143,7 @@ struct vo_frame_s {
* that reason, this flag should be interpreted as a "hint".
*/
int progressive_frame;
+ int picture_coding_type;
/* pan/scan offset */
int pan_scan_x;
@@ -136,6 +161,9 @@ struct vo_frame_s {
int flags; /* remember the frame flags */
int copy_called; /* track use of copy() method */
+ /* used to carry macroblocks information for XvMC acceleration */
+ xine_macroblocks_t *macroblocks;
+
/* "backward" references to where this frame originates from */
xine_video_port_t *port;
vo_driver_t *driver;
@@ -151,7 +179,6 @@ struct vo_frame_s {
int id; /* debugging - track this frame */
int is_first;
-
};
/*
@@ -248,11 +275,12 @@ struct xine_video_port_s {
/* 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_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 */
@@ -269,6 +297,34 @@ struct xine_video_port_s {
#define VO_CAP_CONTRAST 0x00000080 /* driver can set CONTRAST value */
#define VO_CAP_COLORKEY 0x00000100 /* driver can set COLORKEY value */
#define VO_CAP_AUTOPAINT_COLORKEY 0x00000200 /* driver can set AUTOPAINT_COLORKEY value */
+#define VO_CAP_XVMC_MOCOMP 0x00000400 /* driver can set XvMC motion compensation */
+#define VO_CAP_XVMC_IDCT 0x00000800 /* driver can use XvMC idct acceleration */
+
+/* macroblock modes */
+#define XINE_MACROBLOCK_INTRA 1
+#define XINE_MACROBLOCK_PATTERN 2
+#define XINE_MACROBLOCK_MOTION_BACKWARD 4
+#define XINE_MACROBLOCK_MOTION_FORWARD 8
+#define XINE_MACROBLOCK_QUANT 16
+#define XINE_MACROBLOCK_DCT_TYPE_INTERLACED 32
+
+/* motion types */
+#define XINE_MC_FIELD 1
+#define XINE_MC_FRAME 2
+#define XINE_MC_16X8 2
+#define XINE_MC_DMV 3
+
+/* picture coding type */
+#define XINE_PICT_I_TYPE 1
+#define XINE_PICT_P_TYPE 2
+#define XINE_PICT_B_TYPE 3
+#define XINE_PICT_D_TYPE 4
+
+/* xvmc acceleration types */
+#define XINE_VO_MOTION_ACCEL 1
+#define XINE_VO_IDCT_ACCEL 2
+#define XINE_VO_SIGNED_INTRA 4
+
/*
* vo_driver_s contains the functions every display driver
@@ -279,7 +335,7 @@ struct xine_video_port_s {
* from generic vo functions.
*/
-#define VIDEO_OUT_DRIVER_IFACE_VERSION 16
+#define VIDEO_OUT_DRIVER_IFACE_VERSION 17
struct vo_driver_s {