diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2004-09-28 18:49:38 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2004-09-28 18:49:38 +0000 |
commit | fe2a390351727cb5ae264588293f8bd7d6d5198e (patch) | |
tree | 20c91e59d361585dd0d8d45440a96c807ea7dddb /src/libmpeg2 | |
parent | f42eccd3e7c5a717f668f0b832ace09f161dbfbc (diff) | |
download | xine-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.am | 3 | ||||
-rw-r--r-- | src/libmpeg2/decode.c | 146 | ||||
-rw-r--r-- | src/libmpeg2/header.c | 5 | ||||
-rw-r--r-- | src/libmpeg2/mpeg2.h | 9 | ||||
-rw-r--r-- | src/libmpeg2/mpeg2_internal.h | 3 | ||||
-rw-r--r-- | src/libmpeg2/slice_xvmc.c | 9 | ||||
-rw-r--r-- | src/libmpeg2/slice_xvmc_vld.c | 248 | ||||
-rw-r--r-- | src/libmpeg2/xxmc.h | 12 |
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 |