From: Miguel F. <mig...@us...> - 2004-09-28 18:49:50
|
Update of /cvsroot/xine/xine-lib/src/libmpeg2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14456/src/libmpeg2 Modified Files: Makefile.am decode.c header.c mpeg2.h mpeg2_internal.h slice_xvmc.c Added Files: slice_xvmc_vld.c xxmc.h Log Message: 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. --- NEW FILE: slice_xvmc_vld.c --- /* * 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; } } } --- NEW FILE: xxmc.h --- #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 Index: Makefile.am =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libmpeg2/Makefile.am,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- Makefile.am 29 Apr 2004 12:47:39 -0000 1.22 +++ Makefile.am 28 Sep 2004 18:49:39 -0000 1.23 @@ -21,10 +21,11 @@ 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 Index: decode.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libmpeg2/decode.c,v retrieving revision 1.117 retrieving revision 1.118 diff -u -r1.117 -r1.118 --- decode.c 22 Sep 2004 20:29:14 -0000 1.117 +++ decode.c 28 Sep 2004 18:49:39 -0000 1.118 @@ -1,4 +1,4 @@ -/* + /* * decode.c * Copyright (C) 2000-2002 Michel Lespinasse <wa...@zo...> * Copyright (C) 1999-2000 Aaron Holtzman <aho...@es...> @@ -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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } 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 @@ 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) { Index: header.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libmpeg2/header.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- header.c 22 Sep 2004 20:29:14 -0000 1.14 +++ header.c 28 Sep 2004 18:49:39 -0000 1.15 @@ -104,6 +104,8 @@ 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 @@ 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; Index: mpeg2.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libmpeg2/mpeg2.h,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- mpeg2.h 6 Oct 2003 21:52:43 -0000 1.26 +++ mpeg2.h 28 Sep 2004 18:49:39 -0000 1.27 @@ -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 @@ 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 @@ /* 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 @@ * currently */ /* void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); */ + +#endif Index: mpeg2_internal.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libmpeg2/mpeg2_internal.h,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- mpeg2_internal.h 22 Sep 2004 20:29:14 -0000 1.18 +++ mpeg2_internal.h 28 Sep 2004 18:49:39 -0000 1.19 @@ -22,6 +22,7 @@ */ #include "video_out.h" +#include "accel_xvmc.h" /* macroblock modes */ #define MACROBLOCK_INTRA XINE_MACROBLOCK_INTRA @@ -108,6 +109,8 @@ /* 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; Index: slice_xvmc.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libmpeg2/slice_xvmc.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- slice_xvmc.c 26 Oct 2003 11:23:17 -0000 1.4 +++ slice_xvmc.c 28 Sep 2004 18:49:39 -0000 1.5 @@ -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 @@ #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 @@ } } - 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 @@ 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 @@ 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, |