summaryrefslogtreecommitdiff
path: root/src/libmpeg2
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2004-09-28 18:49:38 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2004-09-28 18:49:38 +0000
commitfe2a390351727cb5ae264588293f8bd7d6d5198e (patch)
tree20c91e59d361585dd0d8d45440a96c807ea7dddb /src/libmpeg2
parentf42eccd3e7c5a717f668f0b832ace09f161dbfbc (diff)
downloadxine-lib-fe2a390351727cb5ae264588293f8bd7d6d5198e.tar.gz
xine-lib-fe2a390351727cb5ae264588293f8bd7d6d5198e.tar.bz2
xxmc patch by Thomas Hellstrom (with some changes)
there is still some work to do, please report any breakages. note: new xxmc driver tested with both nvidia and via libraries. CVS patchset: 7007 CVS date: 2004/09/28 18:49:38
Diffstat (limited to 'src/libmpeg2')
-rw-r--r--src/libmpeg2/Makefile.am3
-rw-r--r--src/libmpeg2/decode.c146
-rw-r--r--src/libmpeg2/header.c5
-rw-r--r--src/libmpeg2/mpeg2.h9
-rw-r--r--src/libmpeg2/mpeg2_internal.h3
-rw-r--r--src/libmpeg2/slice_xvmc.c9
-rw-r--r--src/libmpeg2/slice_xvmc_vld.c248
-rw-r--r--src/libmpeg2/xxmc.h12
8 files changed, 412 insertions, 23 deletions
diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am
index c0d06d978..78351525d 100644
--- a/src/libmpeg2/Makefile.am
+++ b/src/libmpeg2/Makefile.am
@@ -21,10 +21,11 @@ xineplug_decode_mpeg2_la_SOURCES = \
motion_comp_vis.c \
slice.c \
slice_xvmc.c \
+ slice_xvmc_vld.c \
stats.c \
xine_decoder.c
xineplug_decode_mpeg2_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB)
xineplug_decode_mpeg2_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
-noinst_HEADERS = vlc.h mpeg2.h mpeg2_internal.h idct_mlib.h vis.h
+noinst_HEADERS = vlc.h mpeg2.h xxmc.h mpeg2_internal.h idct_mlib.h vis.h
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index bb5076489..114e8bc11 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -1,4 +1,4 @@
-/*
+ /*
* decode.c
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
@@ -25,7 +25,6 @@
*/
#include "config.h"
-
#include <stdio.h>
#include <string.h> /* memcpy/memset, try to remove */
#include <stdlib.h>
@@ -42,6 +41,7 @@
#include "mpeg2.h"
#include "mpeg2_internal.h"
#include "xineutils.h"
+#include "xxmc.h"
/*
#define LOG_PAN_SCAN
@@ -90,7 +90,10 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec,
/* initialize substructures */
mpeg2_header_state_init (mpeg2dec->picture);
- if( output->get_capabilities(output) & VO_CAP_XVMC_MOCOMP ) {
+ if ( output->get_capabilities(output) & VO_CAP_XXMC) {
+ printf("libmpeg2: output port has XxMC capability\n");
+ mpeg2dec->frame_format = XINE_IMGFMT_XXMC;
+ } else if( output->get_capabilities(output) & VO_CAP_XVMC_MOCOMP) {
printf("libmpeg2: output port has XvMC capability\n");
mpeg2dec->frame_format = XINE_IMGFMT_XVMC;
} else {
@@ -274,6 +277,38 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
if (is_frame_done && picture->current_frame != NULL) {
+ /*
+ * This frame completion code will move to a separate libmpeg2_accel.c file?
+ * int libmpeg2_accel_frame_completion(mpeg2dec_t *, picture_t *, int);
+ */
+
+ if (mpeg2dec->frame_format == XINE_IMGFMT_XXMC) {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+ switch(xxmc->format) {
+ case XINE_IMGFMT_XXMC:
+ switch(xxmc->acceleration) {
+ case XINE_XVMC_ACCEL_VLD:
+ mpeg2_xxmc_vld_frame_complete(mpeg2dec, picture, code);
+ break;
+ case XINE_XVMC_ACCEL_IDCT:
+ case XINE_XVMC_ACCEL_MOCOMP:
+ xxmc->decoded = !picture->current_frame->bad_frame;
+ xxmc->proc_xxmc_flush( picture->current_frame );
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ * End of frame completion code.
+ */
+
+
if (((picture->picture_structure == FRAME_PICTURE) ||
(picture->second_field)) ) {
@@ -486,7 +521,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->current_frame != picture->forward_reference_frame ) {
picture->current_frame->free (picture->current_frame);
}
- if (picture->picture_coding_type == B_TYPE)
+ if (picture->picture_coding_type == B_TYPE) {
picture->current_frame =
mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out,
picture->coded_picture_width,
@@ -494,7 +529,15 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
get_aspect_ratio(mpeg2dec),
mpeg2dec->frame_format,
flags);
- else {
+ /*
+ * Move to libmpeg2_accel.c
+ * int libmpeg2_accel_new_frame(mpeg2dec_t *, picture_t *)
+ */
+ mpeg2_xxmc_choose_coding(mpeg2dec->frame_format, picture);
+ /*
+ * End of new frame accel code.
+ */
+ } else {
picture->current_frame =
mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out,
picture->coded_picture_width,
@@ -502,6 +545,14 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
get_aspect_ratio(mpeg2dec),
mpeg2dec->frame_format,
flags);
+ /*
+ * Move to libmpeg2_accel.c
+ * int libmpeg2_accel_new_frame(mpeg2dec_t *, picture_t *)
+ */
+ mpeg2_xxmc_choose_coding(mpeg2dec->frame_format, picture);
+ /*
+ * End of new frame accel code.
+ */
if (picture->forward_reference_frame &&
picture->forward_reference_frame != picture->backward_reference_frame)
picture->forward_reference_frame->free (picture->forward_reference_frame);
@@ -510,11 +561,30 @@ 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;
+
+ /*
+ * Move to libmpeg2_accel.c
+ * int libmpeg2_accel_new_sequence(mpeg2dec_t *, picture_t *)
+ */
+
+ if(mpeg2dec->new_sequence) {
+ switch(mpeg2dec->frame_format) {
+ case XINE_IMGFMT_XXMC:
+ case XINE_IMGFMT_XVMC: {
+ xine_xvmc_t *xvmc = (xine_xvmc_t *)
+ picture->current_frame->accel_data;
+ picture->mc = xvmc->macroblocks;
+ mpeg2dec->new_sequence = 0;
+ break;
+ }
+ default:
+ break;
+ }
}
+ /*
+ * End of new sequence accel code.
+ */
+
picture->current_frame->bad_frame = 1;
picture->current_frame->drawn = 0;
picture->current_frame->pts = mpeg2dec->pts;
@@ -543,6 +613,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->current_frame->id, picture->picture_coding_type == I_TYPE ? "I" :
picture->picture_coding_type == P_TYPE ? "P" : "B");
mpeg2dec->pts = 0;
+ /*printf("Starting to decode frame %d\n",picture->current_frame->id);*/
}
}
@@ -551,17 +622,50 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
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);
+ /*
+ * The below accelerated slice function choice will move to libmpeg2_accel.c ?
+ * int libmpeg2_accel_slice(mpeg2dec_t *, picture_t *, int , char *)
+ */
+
+ switch( mpeg2dec->frame_format ) {
+ case XINE_IMGFMT_XXMC:
+ {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+ switch(xxmc->format) {
+ case XINE_IMGFMT_XXMC:
+ switch(xxmc->acceleration) {
+ case XINE_XVMC_ACCEL_VLD:
+ mpeg2_xxmc_slice(mpeg2dec, picture, code, buffer);
+ break;
+ case XINE_XVMC_ACCEL_IDCT:
+ case XINE_XVMC_ACCEL_MOCOMP:
+ mpeg2_xvmc_slice (picture, code, buffer);
+ break;
+ default:
+ mpeg2_slice (picture, code, buffer);
+ break;
+ }
+ break;
+ default:
+ mpeg2_slice (picture, code, buffer);
+ break;
+ }
+ break;
+ }
+ case XINE_IMGFMT_XVMC:
+ mpeg2_xvmc_slice (picture, code, buffer);
+ break;
+ default:
+ mpeg2_slice (picture, code, buffer);
+ break;
}
+ /*
+ * End of acceleration code.
+ */
if( picture->v_offset > picture->limit_y ) {
picture->current_frame->bad_frame = 0;
- lprintf("frame %d successfuly decoded\n",picture->current_frame->id);
}
}
}
@@ -604,6 +708,7 @@ static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec,
}
}
mpeg2dec->code = byte;
+ mpeg2dec->chunk_size = chunk_ptr - mpeg2dec->chunk_buffer - 3;
mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
mpeg2dec->shift = 0xffffff00;
return current;
@@ -652,6 +757,15 @@ void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec) {
picture->forward_reference_frame->pts = 0;
if ( picture->backward_reference_frame )
picture->backward_reference_frame->pts = 0;
+
+ /*
+ * Move to libmpeg2_accel.c
+ * int libmpeg2_accel_discontinuity(mpeg2dec_t *);
+ */
+ mpeg2dec->xxmc_last_slice_code=-1;
+ /*
+ * End of discontinuity accel code.
+ */
}
void mpeg2_reset (mpeg2dec_t * mpeg2dec) {
diff --git a/src/libmpeg2/header.c b/src/libmpeg2/header.c
index 0f10588b0..e435fb405 100644
--- a/src/libmpeg2/header.c
+++ b/src/libmpeg2/header.c
@@ -104,6 +104,8 @@ static uint32_t get_bits(uint8_t *buffer, uint32_t count, uint32_t *bit_position
void mpeg2_header_state_init (picture_t * picture)
{
picture->scan = mpeg2_scan_norm;
+ picture->load_intra_quantizer_matrix = 1;
+ picture->load_non_intra_quantizer_matrix = 1;
}
int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer)
@@ -150,7 +152,8 @@ int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer)
else
for (i = 0; i < 64; i++)
picture->non_intra_quantizer_matrix[i] = 16;
-
+ picture->load_intra_quantizer_matrix = 1;
+ picture->load_non_intra_quantizer_matrix = 1;
/* MPEG1 - for testing only */
picture->mpeg1 = 1;
picture->intra_dc_precision = 0;
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index b6500d1ef..b2ecf669e 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -21,6 +21,9 @@
/* Structure for the mpeg2dec decoder */
+#ifndef MPEG2_H
+#define MPEG2_H
+
typedef struct mpeg2dec_s {
xine_video_port_t * output;
uint32_t frame_format;
@@ -45,6 +48,7 @@ typedef struct mpeg2dec_s {
uint8_t * chunk_ptr;
/* last start code ? */
uint8_t code;
+ uint32_t chunk_size;
int64_t pts;
uint32_t rff_pattern;
@@ -55,7 +59,8 @@ typedef struct mpeg2dec_s {
/* a spu decoder for possible closed captions */
spu_decoder_t *cc_dec;
-
+ int xxmc_last_slice_code;
+ unsigned xxmc_mb_pic_height;
} mpeg2dec_t ;
@@ -81,3 +86,5 @@ void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec);
* currently
*/
/* void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); */
+
+#endif
diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h
index 6ec414789..27611e132 100644
--- a/src/libmpeg2/mpeg2_internal.h
+++ b/src/libmpeg2/mpeg2_internal.h
@@ -22,6 +22,7 @@
*/
#include "video_out.h"
+#include "accel_xvmc.h"
/* macroblock modes */
#define MACROBLOCK_INTRA XINE_MACROBLOCK_INTRA
@@ -108,6 +109,8 @@ typedef struct picture_s {
/* sequence header stuff */
uint8_t intra_quantizer_matrix [64];
uint8_t non_intra_quantizer_matrix [64];
+ int load_intra_quantizer_matrix;
+ int load_non_intra_quantizer_matrix;
/* The width and height of the picture snapped to macroblock units */
int coded_picture_width;
diff --git a/src/libmpeg2/slice_xvmc.c b/src/libmpeg2/slice_xvmc.c
index ec23e25ad..1f6176e78 100644
--- a/src/libmpeg2/slice_xvmc.c
+++ b/src/libmpeg2/slice_xvmc.c
@@ -34,7 +34,7 @@
#include "xineutils.h"
#include "attributes.h"
-
+#include "accel_xvmc.h"
#define MOTION_ACCEL XINE_VO_MOTION_ACCEL
#define IDCT_ACCEL XINE_VO_IDCT_ACCEL
@@ -1700,6 +1700,7 @@ void mpeg2_xvmc_slice (picture_t * picture, int code, uint8_t * buffer)
#define bits (picture->bitstream_bits)
#define bit_ptr (picture->bitstream_ptr)
cpu_state_t cpu_state;
+ xine_xvmc_t *xvmc = (xine_xvmc_t *) picture->current_frame->accel_data;
bitstream_init (picture, buffer);
@@ -1889,7 +1890,7 @@ void mpeg2_xvmc_slice (picture_t * picture, int code, uint8_t * buffer)
}
}
- picture->current_frame->proc_macro_block(picture->XvMC_x, picture->XvMC_y,
+ xvmc->proc_macro_block(picture->XvMC_x, picture->XvMC_y,
picture->XvMC_mb_type,
picture->XvMC_motion_type,
picture->XvMC_mv_field_sel,
@@ -1965,7 +1966,7 @@ void mpeg2_xvmc_slice (picture_t * picture, int code, uint8_t * buffer)
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,
+ xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y,
picture->XvMC_mb_type,
picture->XvMC_motion_type,
picture->XvMC_mv_field_sel,
@@ -2004,7 +2005,7 @@ void mpeg2_xvmc_slice (picture_t * picture, int code, uint8_t * buffer)
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,
+ xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y,
picture->XvMC_mb_type,
picture->XvMC_motion_type,
picture->XvMC_mv_field_sel,
diff --git a/src/libmpeg2/slice_xvmc_vld.c b/src/libmpeg2/slice_xvmc_vld.c
new file mode 100644
index 000000000..950ec1f63
--- /dev/null
+++ b/src/libmpeg2/slice_xvmc_vld.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2004 The Unichrome project. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ */
+
+#include "xine_internal.h"
+#include "video_out.h"
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+#include "xxmc.h"
+
+static uint8_t zig_zag_scan[64] ATTR_ALIGN(16) =
+{
+ /* Zig-Zag scan pattern */
+ 0, 1, 8,16, 9, 2, 3,10,
+ 17,24,32,25,18,11, 4, 5,
+ 12,19,26,33,40,48,41,34,
+ 27,20,13, 6, 7,14,21,28,
+ 35,42,49,56,57,50,43,36,
+ 29,22,15,23,30,37,44,51,
+ 58,59,52,45,38,31,39,46,
+ 53,60,61,54,47,55,62,63
+};
+
+static uint8_t alternate_scan [64] ATTR_ALIGN(16) =
+{
+ /* Alternate scan pattern */
+ 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
+ 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
+ 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
+ 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
+};
+
+
+
+
+void mpeg2_xxmc_choose_coding(int decoder_format, picture_t *picture)
+{
+ if (picture->current_frame) {
+ if (XINE_IMGFMT_XXMC == decoder_format) {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+
+ /*
+ * Make a request for acceleration type and mpeg coding from
+ * the output plugin.
+ */
+
+ xxmc->format = XINE_IMGFMT_XXMC;
+ xxmc->acceleration = XINE_XVMC_ACCEL_VLD| XINE_XVMC_ACCEL_IDCT
+ | XINE_XVMC_ACCEL_MOCOMP ;
+ xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2;
+ xxmc->proc_xxmc_frame(picture->current_frame);
+ }
+ }
+}
+
+
+void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
+ uint8_t *buffer)
+{
+ vo_frame_t
+ *frame = picture->current_frame;
+ xine_xxmc_t
+ *xxmc = (xine_xxmc_t *) frame->accel_data;
+ xine_vld_frame_t
+ *vft = &xxmc->vld_frame;
+ unsigned
+ mb_frame_height;
+ int
+ i;
+ const uint8_t *
+ scan_pattern;
+ float
+ ms_per_slice;
+
+ if (1 == code) {
+ frame->bad_frame = 1;
+
+ /*
+ * Check that first field went through OK. Otherwise,
+ * indicate bad frame.
+ */
+
+ if (picture->second_field) {
+ mpeg2dec->xxmc_last_slice_code = (xxmc->decoded) ? 0 : -1;
+ xxmc->decoded = 0;
+ } else {
+ mpeg2dec->xxmc_last_slice_code = 0;
+ }
+
+ mb_frame_height =
+ (!(picture->mpeg1) && (picture->progressive_sequence)) ?
+ 2*((picture->coded_picture_height+31) >> 5) :
+ (picture->coded_picture_height+15) >> 4;
+ mpeg2dec->xxmc_mb_pic_height = (picture->picture_structure == FRAME_PICTURE ) ?
+ mb_frame_height : mb_frame_height >> 1;
+
+ ms_per_slice = 1000. / (90000. * mb_frame_height) * frame->duration;
+ xxmc->sleep = 1. / (ms_per_slice * 0.45);
+ if (xxmc->sleep < 1.) xxmc->sleep = 1.;
+
+ if (picture->mpeg1) {
+ vft->mv_ranges[0][0] = picture->b_motion.f_code[0];
+ vft->mv_ranges[0][1] = picture->b_motion.f_code[0];
+ vft->mv_ranges[1][0] = picture->f_motion.f_code[0];
+ vft->mv_ranges[1][1] = picture->f_motion.f_code[0];
+ } else {
+ vft->mv_ranges[0][0] = picture->b_motion.f_code[0];
+ vft->mv_ranges[0][1] = picture->b_motion.f_code[1];
+ vft->mv_ranges[1][0] = picture->f_motion.f_code[0];
+ vft->mv_ranges[1][1] = picture->f_motion.f_code[1];
+ }
+
+ vft->picture_structure = picture->picture_structure;
+ vft->picture_coding_type = picture->picture_coding_type;
+ vft->mpeg_coding = (picture->mpeg1) ? 0 : 1;
+ vft->progressive_sequence = picture->progressive_sequence;
+ vft->scan = (picture->scan == mpeg2_scan_alt);
+ vft->pred_dct_frame = picture->frame_pred_frame_dct;
+ vft->concealment_motion_vectors =
+ picture->concealment_motion_vectors;
+ vft->q_scale_type = picture->q_scale_type;
+ vft->intra_vlc_format = picture->intra_vlc_format;
+ vft->intra_dc_precision = picture->intra_dc_precision;
+ vft->second_field = picture->second_field;
+
+ /*
+ * Translation of libmpeg2's Q-matrix layout to VLD XvMC's.
+ * Errors here will give
+ * blocky artifacts and sometimes wrong colors.
+ */
+
+ scan_pattern = (vft->scan) ? alternate_scan : zig_zag_scan;
+
+ if ((vft->load_intra_quantizer_matrix = picture->load_intra_quantizer_matrix)) {
+ for (i=0; i<64; ++i) {
+ vft->intra_quantizer_matrix[scan_pattern[i]] =
+ picture->intra_quantizer_matrix[picture->scan[i]];
+ }
+ }
+
+ if ((vft->load_non_intra_quantizer_matrix = picture->load_non_intra_quantizer_matrix)) {
+ for (i=0; i<64; ++i) {
+ vft->non_intra_quantizer_matrix[scan_pattern[i]] =
+ picture->non_intra_quantizer_matrix[picture->scan[i]];
+ }
+ }
+
+ picture->load_intra_quantizer_matrix = 0;
+ picture->load_non_intra_quantizer_matrix = 0;
+ vft->forward_reference_frame = picture->forward_reference_frame;
+ vft->backward_reference_frame = picture->backward_reference_frame;
+ xxmc->proc_xxmc_begin( frame );
+ if (xxmc->result != 0) {
+ xxmc->proc_xxmc_flush( frame );
+ mpeg2dec->xxmc_last_slice_code=-1;
+ }
+ }
+
+ if ((code == mpeg2dec->xxmc_last_slice_code + 1) &&
+ code <= mpeg2dec->xxmc_mb_pic_height) {
+
+ /*
+ * Send this slice to the output plugin. May stall for a long
+ * time in proc_slice;
+ */
+
+ frame->bad_frame = 1;
+ xxmc->slice_data_size = mpeg2dec->chunk_size;
+ xxmc->slice_data = mpeg2dec->chunk_buffer;
+ xxmc->slice_code = code;
+
+ xxmc->proc_xxmc_slice( frame );
+ if (xxmc->result != 0) {
+ xxmc->proc_xxmc_flush( frame );
+ mpeg2dec->xxmc_last_slice_code=-1;
+ return;
+ }
+
+ if (code == mpeg2dec->xxmc_mb_pic_height) {
+
+ /*
+ * We've encountered the last slice of this frame.
+ * Release the decoder for a new frame and, if all
+ * went well, tell libmpeg2 that we are ready.
+ */
+
+ mpeg2_xxmc_vld_frame_complete(mpeg2dec,picture,code);
+ return;
+ } else {
+
+ /*
+ * Keep track of slices.
+ */
+
+ mpeg2dec->xxmc_last_slice_code++;
+ }
+
+ } else {
+
+ /*
+ * An error has occured.
+ */
+
+ lprintf("libmpeg2: VLD XvMC: Slice error.\n");
+ mpeg2dec->xxmc_last_slice_code = -1;
+ xxmc->proc_xxmc_flush( frame );
+ return;
+ }
+}
+
+void mpeg2_xxmc_vld_frame_complete(mpeg2dec_t *mpeg2dec, picture_t *picture, int code)
+{
+ vo_frame_t
+ *frame = picture->current_frame;
+ xine_xxmc_t
+ *xxmc = (xine_xxmc_t *) frame->accel_data;
+
+ if (xxmc->decoded) return;
+ if (mpeg2dec->xxmc_last_slice_code >= 1) {
+ xxmc->proc_xxmc_flush( frame );
+ if (xxmc->result) {
+ mpeg2dec->xxmc_last_slice_code=-1;
+ return;
+ }
+ xxmc->decoded = 1;
+ mpeg2dec->xxmc_last_slice_code++;
+ if (picture->picture_structure == 3 || picture->second_field) {
+ if (xxmc->result == 0)
+ frame->bad_frame = 0;
+ }
+ }
+}
diff --git a/src/libmpeg2/xxmc.h b/src/libmpeg2/xxmc.h
new file mode 100644
index 000000000..c4221200b
--- /dev/null
+++ b/src/libmpeg2/xxmc.h
@@ -0,0 +1,12 @@
+#ifndef _XXMC_H
+#define _XXMC_H
+
+#include "accel_xvmc.h"
+
+extern void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture,
+ int code, uint8_t *buffer);
+extern void mpeg2_xxmc_choose_coding(int decoder_format, picture_t *picture);
+
+extern void mpeg2_xxmc_vld_frame_complete(mpeg2dec_t *mpeg2dec, picture_t *picture, int code);
+
+#endif