+++ /dev/null
-/* $Id$
- * mpeg2_internal.h
- * Copyright (C) 2000-2003 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
- */
-
-#ifndef LIBMPEG2_MPEG2_INTERNAL_H
-#define LIBMPEG2_MPEG2_INTERNAL_H
-
-#define STATE_INTERNAL_NORETURN ((mpeg2_state_t)-1)
-
-/* 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
-/* motion_type */
-#define MOTION_TYPE_SHIFT 6
-#define MC_FIELD 1
-#define MC_FRAME 2
-#define MC_16X8 2
-#define MC_DMV 3
-
-/* picture structure */
-#define TOP_FIELD 1
-#define BOTTOM_FIELD 2
-#define FRAME_PICTURE 3
-
-/* picture coding type */
-#define I_TYPE 1
-#define P_TYPE 2
-#define B_TYPE 3
-#define D_TYPE 4
-
-typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int);
-
-typedef struct {
- uint8_t * ref[2][3];
- uint8_t ** ref2[2];
- int pmv[2][2];
- int f_code[2];
-} motion_t;
-
-typedef void motion_parser_t (mpeg2_decoder_t * decoder,
- motion_t * motion,
- mpeg2_mc_fct * const * table);
-
-struct mpeg2_decoder_s {
- /* first, state that carries information from one macroblock to the */
- /* next inside a slice, and is never used outside of mpeg2_slice() */
-
- /* bit parsing stuff */
- uint32_t bitstream_buf; /* current 32 bit working set */
- int bitstream_bits; /* used bits in working set */
- const uint8_t * bitstream_ptr; /* buffer with stream data */
-
- uint8_t * dest[3];
-
- int offset;
- int stride;
- int uv_stride;
- int slice_stride;
- int slice_uv_stride;
- int stride_frame;
- unsigned int limit_x;
- unsigned int limit_y_16;
- unsigned int limit_y_8;
- unsigned int limit_y;
-
- /* Motion vectors */
- /* The f_ and b_ correspond to the forward and backward motion */
- /* predictors */
- motion_t b_motion;
- motion_t f_motion;
- motion_parser_t * motion_parser[5];
-
- /* predictor for DC coefficients in intra blocks */
- int16_t dc_dct_pred[3];
-
- /* DCT coefficients */
- int16_t DCTblock[64] ATTR_ALIGN(64);
-
- uint8_t * picture_dest[3];
- void (* convert) (void * convert_id, uint8_t * const * src,
- unsigned int v_offset);
- void * convert_id;
-
- int dmv_offset;
- unsigned int v_offset;
-
- /* now non-slice-specific information */
-
- /* sequence header stuff */
- uint16_t * quantizer_matrix[4];
- uint16_t (* chroma_quantizer[2])[64];
- uint16_t quantizer_prescale[4][32][64];
-
- /* The width and height of the picture snapped to macroblock units */
- int width;
- int height;
- int vertical_position_extension;
- int chroma_format;
-
- /* picture header stuff */
-
- /* what type of picture this is (I, P, B, D) */
- int coding_type;
-
- /* picture coding extension stuff */
-
- /* quantization factor for intra dc coefficients */
- int intra_dc_precision;
- /* top/bottom/both fields */
- int picture_structure;
- /* bool to indicate all predictions are frame based */
- int frame_pred_frame_dct;
- /* bool to indicate whether intra blocks have motion vectors */
- /* (for concealment) */
- int concealment_motion_vectors;
- /* bool to use different vlc tables */
- int intra_vlc_format;
- /* used for DMV MC */
- int top_field_first;
-
- /* stuff derived from bitstream */
-
- /* pointer to the zigzag scan we're supposed to be using */
- const uint8_t * scan;
-
- int second_field;
-
- int mpeg1;
-
- /* XXX: stuff due to xine shit */
- int8_t q_scale_type;
-};
-
-typedef struct {
- mpeg2_fbuf_t fbuf;
-} fbuf_alloc_t;
-
-struct mpeg2dec_s {
- mpeg2_decoder_t decoder;
-
- mpeg2_info_t info;
-
- uint32_t shift;
- int is_display_initialized;
- mpeg2_state_t (* action) (struct mpeg2dec_s * mpeg2dec);
- mpeg2_state_t state;
- uint32_t ext_state;
-
- /* allocated in init - gcc has problems allocating such big structures */
- uint8_t * chunk_buffer;
- /* pointer to start of the current chunk */
- uint8_t * chunk_start;
- /* pointer to current position in chunk_buffer */
- uint8_t * chunk_ptr;
- /* last start code ? */
- uint8_t code;
-
- /* picture tags */
- uint32_t tag_current, tag2_current, tag_previous, tag2_previous;
- int num_tags;
- int bytes_since_tag;
-
- int first;
- int alloc_index_user;
- int alloc_index;
- uint8_t first_decode_slice;
- uint8_t nb_decode_slices;
-
- unsigned int user_data_len;
-
- mpeg2_sequence_t new_sequence;
- mpeg2_sequence_t sequence;
- mpeg2_gop_t new_gop;
- mpeg2_gop_t gop;
- mpeg2_picture_t new_picture;
- mpeg2_picture_t pictures[4];
- mpeg2_picture_t * picture;
- /*const*/ mpeg2_fbuf_t * fbuf[3]; /* 0: current fbuf, 1-2: prediction fbufs */
-
- fbuf_alloc_t fbuf_alloc[3];
- int custom_fbuf;
-
- uint8_t * yuv_buf[3][3];
- int yuv_index;
- mpeg2_convert_t * convert;
- void * convert_arg;
- unsigned int convert_id_size;
- int convert_stride;
- void (* convert_start) (void * id, const mpeg2_fbuf_t * fbuf,
- const mpeg2_picture_t * picture,
- const mpeg2_gop_t * gop);
-
- uint8_t * buf_start;
- uint8_t * buf_end;
-
- int16_t display_offset_x, display_offset_y;
-
- int copy_matrix;
- int8_t scaled[4]; /* XXX: MOVED */
- //int8_t q_scale_type, scaled[4];
- uint8_t quantizer_matrix[4][64];
- uint8_t new_quantizer_matrix[4][64];
-};
-
-typedef struct {
-#ifdef ARCH_PPC
- uint8_t regv[12*16];
-#endif
- int dummy;
-} cpu_state_t;
-
-/* cpu_accel.c */
-uint32_t mpeg2_detect_accel (uint32_t accel);
-
-/* cpu_state.c */
-void mpeg2_cpu_state_init (uint32_t accel);
-
-/* decode.c */
-mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec);
-
-/* header.c */
-void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec);
-void mpeg2_reset_info (mpeg2_info_t * info);
-int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_gop (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_picture (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_extension (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec);
-void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec);
-void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec);
-void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels);
-mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec);
-void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type);
-
-/* idct.c */
-extern void mpeg2_idct_init (uint32_t accel);
-extern uint8_t mpeg2_scan_norm[64];
-extern uint8_t mpeg2_scan_alt[64];
-
-/* idct_mmx.c */
-void mpeg2_idct_copy_sse2 (int16_t * block, uint8_t * dest, int stride);
-void mpeg2_idct_add_sse2 (int last, int16_t * block,
- uint8_t * dest, int stride);
-void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride);
-void mpeg2_idct_add_mmxext (int last, int16_t * block,
- uint8_t * dest, int stride);
-void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride);
-void mpeg2_idct_add_mmx (int last, int16_t * block,
- uint8_t * dest, int stride);
-void mpeg2_idct_mmx_init (void);
-
-/* idct_altivec.c */
-void mpeg2_idct_copy_altivec (int16_t * block, uint8_t * dest, int stride);
-void mpeg2_idct_add_altivec (int last, int16_t * block,
- uint8_t * dest, int stride);
-void mpeg2_idct_altivec_init (void);
-
-/* idct_alpha.c */
-void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, int stride);
-void mpeg2_idct_add_mvi (int last, int16_t * block,
- uint8_t * dest, int stride);
-void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, int stride);
-void mpeg2_idct_add_alpha (int last, int16_t * block,
- uint8_t * dest, int stride);
-void mpeg2_idct_alpha_init (void);
-
-/* motion_comp.c */
-void mpeg2_mc_init (uint32_t accel);
-
-typedef struct {
- mpeg2_mc_fct * put [8];
- mpeg2_mc_fct * avg [8];
-} mpeg2_mc_t;
-
-#define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \
- {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \
- MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \
- {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \
- MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \
-};
-
-extern mpeg2_mc_t mpeg2_mc_c;
-extern mpeg2_mc_t mpeg2_mc_mmx;
-extern mpeg2_mc_t mpeg2_mc_mmxext;
-extern mpeg2_mc_t mpeg2_mc_3dnow;
-extern mpeg2_mc_t mpeg2_mc_altivec;
-extern mpeg2_mc_t mpeg2_mc_alpha;
-extern mpeg2_mc_t mpeg2_mc_vis;
-extern mpeg2_mc_t mpeg2_mc_arm;
-
-#endif /* LIBMPEG2_MPEG2_INTERNAL_H */
+++ /dev/null
-/*****************************************************************************
- * xxmc.c : HW MPEG decoder thread
- *****************************************************************************
- * Copyright (C) 2000-2001 VideoLAN
- * $Id$
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- * Laurent Aimar <fenrir@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_plugin.h>
-#include <vlc_codec.h>
-#include <vlc_codec_synchro.h>
-#include <vlc_cpu.h>
-
-#include <unistd.h>
-#ifdef __GLIBC__
- #include <mcheck.h>
-#endif
-
-#include "mpeg2.h"
-//#include "attributes.h"
-#include "mpeg2_internal.h"
-//#include "xvmc_vld.h"
-
-/* Aspect ratio (ISO/IEC 13818-2 section 6.3.3, table 6-3) */
-#define AR_SQUARE_PICTURE 1 /* square pixels */
-#define AR_3_4_PICTURE 2 /* 3:4 picture (TV) */
-#define AR_16_9_PICTURE 3 /* 16:9 picture (wide screen) */
-#define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */
-
-/*****************************************************************************
- * decoder_sys_t : libmpeg2 decoder descriptor
- *****************************************************************************/
-struct decoder_sys_t
-{
- /*
- * libmpeg2 properties
- */
- mpeg2dec_t *p_mpeg2dec;
- const mpeg2_info_t *p_info;
- bool b_skip;
-
- /*
- * Input properties
- */
- mtime_t i_pts;
- mtime_t i_previous_pts;
- mtime_t i_current_pts;
- mtime_t i_previous_dts;
- mtime_t i_current_dts;
- int i_current_rate;
- picture_t * p_picture_to_destroy;
- bool b_garbage_pic;
- bool b_after_sequence_header; /* is it the next frame after
- * the sequence header ? */
- bool b_slice_i; /* intra-slice refresh stream */
-
- /*
- * Output properties
- */
- decoder_synchro_t *p_synchro;
- int i_aspect;
- mtime_t i_last_frame_pts;
-};
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-
-static int OpenDecoder( vlc_object_t * );
-static void CloseDecoder( vlc_object_t * );
-
-static picture_t *DecodeBlock( decoder_t *, block_t ** );
-
-static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-vlc_module_begin ()
- set_description( N_("MPEG I/II hw video decoder (using libmpeg2)") )
- set_capability( "decoder", 140 )
- set_callbacks( OpenDecoder, CloseDecoder )
- add_shortcut( "xxmc" )
-vlc_module_end ()
-
-/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************/
-static int OpenDecoder( vlc_object_t *p_this )
-{
-
- decoder_t *p_dec = (decoder_t*)p_this;
- decoder_sys_t *p_sys = NULL;
- uint32_t i_accel = 0;
- FILE *f_wd_dec;
-
-#ifdef __GLIBC__
- mtrace();
-#endif
- if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGV )
- return VLC_EGENERIC;
- /* Select onl recognized original format (standard mpeg video) */
- switch( p_dec->fmt_in.i_original_fourcc )
- {
- case VLC_FOURCC('m','p','g','1'):
- case VLC_FOURCC('m','p','g','2'):
- case VLC_FOURCC('m','p','g','v'):
- /* Pinnacle hardware-mpeg1 */
- case VLC_FOURCC('P','I','M','1'):
- /* VIA hardware-mpeg2 */
- case VLC_FOURCC('X','x','M','C'):
- /* ATI Video */
- case VLC_FOURCC('V','C','R','2'):
- break;
- default:
- if( p_dec->fmt_in.i_original_fourcc )
- return VLC_EGENERIC;
- break;
- }
-
- msg_Dbg(p_dec, "OpenDecoder Entering");
-
- /* Allocate the memory needed to store the decoder's structure */
- p_dec->p_sys = p_sys = calloc( 1, sizeof(*p_sys) );
- if( !p_sys )
- return VLC_ENOMEM;
-
- /* Initialize the thread properties */
- p_sys->p_mpeg2dec = NULL;
- p_sys->p_synchro = NULL;
- p_sys->p_info = NULL;
- p_sys->i_pts = mdate() + DEFAULT_PTS_DELAY;
- p_sys->i_current_pts = 0;
- p_sys->i_previous_pts = 0;
- p_sys->i_current_dts = 0;
- p_sys->i_previous_dts = 0;
- p_sys->p_picture_to_destroy = NULL;
- p_sys->b_garbage_pic = 0;
- p_sys->b_slice_i = 0;
- p_sys->b_skip = 0;
-
-#if defined( __i386__ )
- if( vlc_CPU() & CPU_CAPABILITY_MMX )
- {
- i_accel |= MPEG2_ACCEL_X86_MMX;
- }
-
- if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
- {
- i_accel |= MPEG2_ACCEL_X86_3DNOW;
- }
-
- if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
- {
- i_accel |= MPEG2_ACCEL_X86_MMXEXT;
- }
-
-#elif defined( __powerpc__ ) || defined( SYS_DARWIN )
- if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
- {
- i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
- }
-
-#else
- /* If we do not know this CPU, trust libmpeg2's feature detection */
- i_accel = MPEG2_ACCEL_DETECT;
-
-#endif
-
- /* Set CPU acceleration features */
- mpeg2_accel( i_accel );
-
- /* Initialize decoder */
- p_sys->p_mpeg2dec = mpeg2_init();
- if( p_sys->p_mpeg2dec == NULL)
- {
- msg_Err( p_dec, "mpeg2_init() failed" );
- free( p_sys );
- return VLC_EGENERIC;
- }
-
- p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
-
- p_dec->pf_decode_video = DecodeBlock;
- p_dec->fmt_out.i_cat = VIDEO_ES;
- p_dec->fmt_out.i_codec = 0;
-
- f_wd_dec = fopen("/vlc/dec_pid", "w");
- if (f_wd_dec != NULL)
- {
- fprintf(f_wd_dec, "%d\n", getpid());
- fflush(f_wd_dec);
- fclose(f_wd_dec);
- }
-
- msg_Dbg(p_dec, "OpenDecoder Leaving");
- return VLC_SUCCESS;
-}
-
-#if 0
-static void WriteDecodeFile(int value)
-{
- FILE *f_wd_ok;
-
- f_wd_ok = fopen("/vlc/dec_ok", "w");
- if (f_wd_ok != NULL)
- {
- fprintf(f_wd_ok, "%d", value);
- fflush(f_wd_ok);
- fclose(f_wd_ok);
- }
-}
-#endif
-
-/*****************************************************************************
- * RunDecoder: the libmpeg2 decoder
- *****************************************************************************/
-static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- mpeg2_state_t state;
- picture_t *p_pic;
-
- block_t *p_block;
-
- if( !pp_block || !*pp_block )
- return NULL;
-
- p_block = *pp_block;
- while( 1 )
- {
- state = mpeg2_parse( p_sys->p_mpeg2dec );
- switch( state )
- {
- case STATE_BUFFER:
- if( !p_block->i_buffer )
- {
- block_Release( p_block );
- return NULL;
- }
- if( (p_block->i_flags&BLOCK_FLAG_DISCONTINUITY) &&
- p_sys->p_synchro &&
- p_sys->p_info->sequence &&
- p_sys->p_info->sequence->width != (unsigned int)-1 )
- {
- decoder_SynchroReset( p_sys->p_synchro );
- if( p_sys->p_info->current_fbuf != NULL
- && p_sys->p_info->current_fbuf->id != NULL )
- {
- p_sys->b_garbage_pic = 1;
- p_pic = p_sys->p_info->current_fbuf->id;
- }
- else
- {
- uint8_t *buf[3];
- buf[0] = buf[1] = buf[2] = NULL;
- if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
- break;
- mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
- }
- p_sys->p_picture_to_destroy = p_pic;
-
- if ( p_sys->b_slice_i )
- {
- decoder_SynchroNewPicture( p_sys->p_synchro,
- I_CODING_TYPE, 2, 0, 0,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
- decoder_SynchroDecode( p_sys->p_synchro );
- decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
- }
- }
-
-#ifdef PIC_FLAG_PTS
- if( p_block->i_pts )
- {
- mpeg2_pts( p_sys->p_mpeg2dec, (uint32_t)p_block->i_pts );
-
-#else /* New interface */
- if( p_block->i_pts || p_block->i_dts )
- {
- mpeg2_tag_picture( p_sys->p_mpeg2dec,
- (uint32_t)p_block->i_pts,
- (uint32_t)p_block->i_dts );
-#endif
- p_sys->i_previous_pts = p_sys->i_current_pts;
- p_sys->i_current_pts = p_block->i_pts;
- p_sys->i_previous_dts = p_sys->i_current_dts;
- p_sys->i_current_dts = p_block->i_dts;
- }
- p_sys->i_current_rate = p_block->i_rate;
-
- mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
- p_block->p_buffer + p_block->i_buffer );
- p_block->i_buffer = 0;
- break;
-
- case STATE_SEQUENCE:
- {
- /* Initialize video output */
- uint8_t *buf[3];
- buf[0] = buf[1] = buf[2] = NULL;
-
- /* Check whether the input gave a particular aspect ratio */
- if( p_dec->fmt_in.video.i_aspect )
- {
- p_sys->i_aspect = p_dec->fmt_in.video.i_aspect;
- if( p_sys->i_aspect <= AR_221_1_PICTURE )
- switch( p_sys->i_aspect )
- {
- case AR_3_4_PICTURE:
- p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
- break;
- case AR_16_9_PICTURE:
- p_sys->i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
- break;
- case AR_221_1_PICTURE:
- p_sys->i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
- break;
- case AR_SQUARE_PICTURE:
- p_sys->i_aspect = VOUT_ASPECT_FACTOR *
- p_sys->p_info->sequence->width /
- p_sys->p_info->sequence->height;
- break;
- }
- }
- else
- {
- /* Use the value provided in the MPEG sequence header */
- if( p_sys->p_info->sequence->pixel_height > 0 )
- {
- p_sys->i_aspect =
- ((uint64_t)p_sys->p_info->sequence->display_width) *
- p_sys->p_info->sequence->pixel_width *
- VOUT_ASPECT_FACTOR /
- p_sys->p_info->sequence->display_height /
- p_sys->p_info->sequence->pixel_height;
- }
- else
- {
- /* Invalid aspect, assume 4:3.
- * This shouldn't happen and if it does it is a bug
- * in libmpeg2 (likely triggered by an invalid stream) */
- p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
- }
- }
-
- msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps",
- p_sys->p_info->sequence->width,
- p_sys->p_info->sequence->height, p_sys->i_aspect,
- (uint32_t)((uint64_t)1001000000 * 27 /
- p_sys->p_info->sequence->frame_period / 1001),
- (uint32_t)((uint64_t)1001000000 * 27 /
- p_sys->p_info->sequence->frame_period % 1001) );
-
- mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
-
- /* Set the first 2 reference frames */
- mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
-
- if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
- {
- block_Release( p_block );
- return NULL;
- }
- mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
-
- p_pic->date = 0;
- decoder_LinkPicture( p_dec, p_pic );
-
- if( p_sys->p_synchro )
- {
- decoder_SynchroRelease( p_sys->p_synchro );
- }
- p_sys->p_synchro = decoder_SynchroInit( p_dec,
- (uint32_t)((uint64_t)1001000000 * 27 /
- p_sys->p_info->sequence->frame_period) );
- p_sys->b_after_sequence_header = 1;
- }
- break;
-
- case STATE_PICTURE_2ND:
- decoder_SynchroNewPicture( p_sys->p_synchro,
- p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
- p_sys->p_info->current_picture->nb_fields,
- 0, 0,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
-
- if( p_sys->b_skip )
- {
- decoder_SynchroTrash( p_sys->p_synchro );
- }
- else
- {
- decoder_SynchroDecode( p_sys->p_synchro );
- }
- break;
-
- case STATE_PICTURE:
- {
- uint8_t *buf[3];
- mtime_t i_pts;
- buf[0] = buf[1] = buf[2] = NULL;
-
- if ( p_sys->b_after_sequence_header &&
- ((p_sys->p_info->current_picture->flags &
- PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P) )
- {
- /* Intra-slice refresh. Simulate a blank I picture. */
- msg_Dbg( p_dec, "intra-slice refresh stream" );
- decoder_SynchroNewPicture( p_sys->p_synchro,
- I_CODING_TYPE, 2, 0, 0,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
- decoder_SynchroDecode( p_sys->p_synchro );
- decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
- p_sys->b_slice_i = 1;
- }
- p_sys->b_after_sequence_header = 0;
-
-#ifdef PIC_FLAG_PTS
- i_pts = p_sys->p_info->current_picture->flags & PIC_FLAG_PTS ?
- ( ( p_sys->p_info->current_picture->pts ==
- (uint32_t)p_sys->i_current_pts ) ?
- p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
-#else /* New interface */
- i_pts = p_sys->p_info->current_picture->flags & PIC_FLAG_TAGS ?
- ( ( p_sys->p_info->current_picture->tag ==
- (uint32_t)p_sys->i_current_pts ) ?
- p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
-#endif
- /* Hack to handle demuxers which only have DTS timestamps */
- if( !i_pts && !p_block->i_pts && p_block->i_dts > 0 )
- {
- if( p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ||
- (p_sys->p_info->current_picture->flags &
- PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B )
- {
- i_pts = p_block->i_dts;
- }
- }
- p_block->i_pts = p_block->i_dts = 0;
- /* End hack */
-
- decoder_SynchroNewPicture( p_sys->p_synchro,
- p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
- p_sys->p_info->current_picture->nb_fields, i_pts,
- 0,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
-
- if ( !(p_sys->b_slice_i
- && ((p_sys->p_info->current_picture->flags
- & PIC_MASK_CODING_TYPE) == P_CODING_TYPE))
- && !decoder_SynchroChoose( p_sys->p_synchro,
- p_sys->p_info->current_picture->flags
- & PIC_MASK_CODING_TYPE,
- /*FindVout(p_dec)->render_time*/ 0 /*FIXME*/,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ) )
- {
- mpeg2_skip( p_sys->p_mpeg2dec, 1 );
- p_sys->b_skip = 1;
- decoder_SynchroTrash( p_sys->p_synchro );
- mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
- }
- else
- {
- mpeg2_skip( p_sys->p_mpeg2dec, 0 );
- p_sys->b_skip = 0;
- decoder_SynchroDecode( p_sys->p_synchro );
-
- if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
- {
- block_Release( p_block );
- return NULL;
- }
-
- //p_sys->p_mpeg2dec->ptr_forward_ref_picture = p_sys->p_mpeg2dec->fbuf[2]->id;
- //p_sys->p_mpeg2dec->ptr_backward_ref_picture = p_sys->p_mpeg2dec->fbuf[1]->id;
-
- if ((p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) != B_CODING_TYPE)
- {
- //if (p_sys->p_mpeg2dec->ptr_forward_ref_picture &&
- // p_sys->p_mpeg2dec->ptr_forward_ref_picture != picture->backward_reference_frame)
- // p_pic->forward_reference_frame->free (p_pic->forward_reference_frame);
-
- //p_sys->p_mpeg2dec->ptr_forward_ref_picture =
- // p_sys->p_mpeg2dec->ptr_backward_ref_picture;
- //p_sys->p_mpeg2dec->ptr_backward_ref_picture = (void *)p_pic;
- }
- mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
- }
- }
- break;
-
- case STATE_END:
- case STATE_SLICE:
- p_pic = NULL;
- if( p_sys->p_info->display_fbuf
- && p_sys->p_info->display_fbuf->id )
- {
- p_pic = (picture_t *)p_sys->p_info->display_fbuf->id;
-
- decoder_SynchroEnd( p_sys->p_synchro,
- p_sys->p_info->display_picture->flags
- & PIC_MASK_CODING_TYPE,
- p_sys->b_garbage_pic );
- p_sys->b_garbage_pic = 0;
-
- if ( p_sys->p_picture_to_destroy != p_pic )
- {
- p_pic->date = decoder_SynchroDate( p_sys->p_synchro );
- }
- else
- {
- p_sys->p_picture_to_destroy = NULL;
- p_pic->date = 0;
- }
- }
-
- if( p_sys->p_info->discard_fbuf &&
- p_sys->p_info->discard_fbuf->id )
- {
- decoder_UnlinkPicture( p_dec, p_sys->p_info->discard_fbuf->id );
- }
- /* For still frames */
- //if( state == STATE_END && p_pic ) p_pic->b_force = true;
-
- if( p_pic )
- {
-#if 0
- /* Avoid frames with identical timestamps.
- * Especially needed for still frames in DVD menus. */
- if( p_sys->i_last_frame_pts == p_pic->date ) p_pic->date++;
- p_sys->i_last_frame_pts = p_pic->date;
-#endif
- return p_pic;
- }
- break;
-
- case STATE_INVALID:
- {
- uint8_t *buf[3];
- buf[0] = buf[1] = buf[2] = NULL;
-
- msg_Warn( p_dec, "invalid picture encountered" );
- if ( ( p_sys->p_info->current_picture == NULL ) ||
- ( ( p_sys->p_info->current_picture->flags &
- PIC_MASK_CODING_TYPE) != B_CODING_TYPE ) )
- {
- if( p_sys->p_synchro ) decoder_SynchroReset( p_sys->p_synchro );
- }
- mpeg2_skip( p_sys->p_mpeg2dec, 1 );
- p_sys->b_skip = 1;
-
- if( p_sys->p_info->current_fbuf &&
- p_sys->p_info->current_fbuf->id )
- {
- p_sys->b_garbage_pic = 1;
- p_pic = p_sys->p_info->current_fbuf->id;
- }
- else if( !p_sys->p_info->sequence )
- {
- break;
- }
- else
- {
- if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
- break;
- mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
- }
- p_sys->p_picture_to_destroy = p_pic;
-
- memset( p_pic->p[0].p_pixels, 0,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height );
- memset( p_pic->p[1].p_pixels, 0x80,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height / 4 );
- memset( p_pic->p[2].p_pixels, 0x80,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height / 4 );
-
- if( p_sys->b_slice_i )
- {
- decoder_SynchroNewPicture( p_sys->p_synchro,
- I_CODING_TYPE, 2, 0, 0,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
- decoder_SynchroDecode( p_sys->p_synchro );
- decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
- }
- break;
- }
-
- default:
- break;
- }
- }
- return NULL;
-}
-
-/*****************************************************************************
- * CloseDecoder: libmpeg2 decoder destruction
- *****************************************************************************/
-static void CloseDecoder( vlc_object_t *p_this )
-{
- decoder_t *p_dec = (decoder_t *)p_this;
- decoder_sys_t *p_sys = p_dec->p_sys;
- FILE *f_wd_dec;
-
- if( p_sys->p_synchro ) decoder_SynchroRelease( p_sys->p_synchro );
- if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
-
- f_wd_dec = fopen("/vlc/dec_pid", "w");
- if (f_wd_dec != NULL)
- {
- fprintf(f_wd_dec, "0\n");
- fflush(f_wd_dec);
- fclose(f_wd_dec);
- }
- free( p_sys );
-}
-
-#if 0
-static double get_aspect_ratio( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- double ratio;
- double mpeg1_pel_ratio[16] = {1.0 /* forbidden */,
- 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157,
- 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ };
-
- if( !p_sys->p_mpeg2dec->decoder.mpeg1 )
- {
- /* these hardcoded values are defined on mpeg2 standard for
- * aspect ratio. other values are reserved or forbidden. */
- /*switch( p_sys->p_mpeg2dec->decoder.aspect_ratio_information )
- {
- case 2:
- ratio = 4.0/3.0;
- break;
- case 3:
- ratio = 16.0/9.0;
- break;
- case 4:
- ratio = 2.11/1.0;
- break;
- case 1:
- default:*/
- ratio = (double)p_sys->p_mpeg2dec->decoder.width/(double)p_sys->p_mpeg2dec->decoder.height;
- /* break;
- }*/
- }
- else
- {
- /* mpeg1 constants refer to pixel aspect ratio */
- ratio = (double)p_sys->p_mpeg2dec->decoder.width/(double)p_sys->p_mpeg2dec->decoder.height;
- /* ratio /= mpeg1_pel_ratio[p_sys->p_mpeg2dec->decoder.aspect_ratio_information]; */
- }
- return ratio;
-}
-#endif
-
-/*****************************************************************************
- * GetNewPicture: Get a new picture from the vout and set the buf struct
- *****************************************************************************/
-static picture_t *GetNewPicture( decoder_t *p_dec, uint8_t **pp_buf )
-{
- //msg_Dbg(p_dec, "GetNewPicture Entering");
- decoder_sys_t *p_sys = p_dec->p_sys;
- picture_t *p_pic;
-
- p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
- p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
- p_dec->fmt_out.video.i_aspect = p_sys->i_aspect;
-
- if( p_sys->p_info->sequence->frame_period > 0 )
- {
- p_dec->fmt_out.video.i_frame_rate =
- (uint32_t)( (uint64_t)1001000000 * 27 /
- p_sys->p_info->sequence->frame_period );
- p_dec->fmt_out.video.i_frame_rate_base = 1001;
- }
-
- p_dec->fmt_out.i_codec =
- ( p_sys->p_info->sequence->chroma_height <
- p_sys->p_info->sequence->height ) ?
- VLC_CODEC_I420 : VLC_CODEC_I422;
-
-#if 0
- p_sys->f_wd_nb = fopen("/vlc/dec_nb", "w");
- if (p_sys->f_wd_nb != NULL)
- {
-// fprintf(p_sys->f_wd_nb, "%d\n", mdate());
- fprintf(p_sys->f_wd_nb, "%s\n", mdate());
- fflush(p_sys->f_wd_nb);
- }
-#endif
- p_pic = decoder_NewPicture( p_dec );
-
- if( p_pic == NULL ) return NULL;
-
- p_pic->b_progressive = p_sys->p_info->current_picture != NULL ?
- p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
- p_pic->b_top_field_first = p_sys->p_info->current_picture != NULL ?
- p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
- p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ?
- p_sys->p_info->current_picture->nb_fields : 2;
- p_pic->format.i_frame_rate = p_dec->fmt_out.video.i_frame_rate;
- p_pic->format.i_frame_rate_base = p_dec->fmt_out.video.i_frame_rate_base;
-
- decoder_LinkPicture( p_dec, p_pic );
-
- pp_buf[0] = p_pic->p[0].p_pixels;
- pp_buf[1] = p_pic->p[1].p_pixels;
- pp_buf[2] = p_pic->p[2].p_pixels;
-
- /* let driver ensure this image has the right format */
-#if 0
- this->driver->update_frame_format( p_pic->p_sys->p_vout, p_pic,
- p_dec->fmt_out.video.i_width,
- p_dec->fmt_out.video.i_height,
- p_dec->fmt_out.video.i_aspect,
- format, flags);
- mpeg2_xxmc_choose_coding( p_dec, &p_sys->p_mpeg2dec->decoder, p_pic,
- get_aspect_ratio(p_dec), 0 );
-#endif
- return p_pic;
-}
+++ /dev/null
-/*****************************************************************************
- * xvmc.c : XVMC plugin for vlc
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id$
- *
- * Authors: Shane Harper <shanegh@optusnet.com.au>
- * Vincent Seguin <seguin@via.ecp.fr>
- * Samuel Hocevar <sam@zoy.org>
- * David Kennedy <dkennedy@tinytoad.com>
- * Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_plugin.h>
-#include <vlc_interface.h>
-#include <vlc_vout.h>
-#include <vlc_keys.h>
-
-#ifdef HAVE_MACHINE_PARAM_H
- /* BSD */
-# include <machine/param.h>
-# include <sys/types.h> /* typedef ushort */
-# include <sys/ipc.h>
-#endif
-
-#ifndef WIN32
-# include <netinet/in.h> /* BSD: struct in_addr */
-#endif
-
-#ifdef HAVE_SYS_SHM_H
-# include <sys/shm.h> /* shmget(), shmctl() */
-#endif
-
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#ifdef HAVE_SYS_SHM_H
-# include <X11/extensions/XShm.h>
-#endif
-#ifdef DPMSINFO_IN_DPMS_H
-# include <X11/extensions/dpms.h>
-#endif
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/vldXvMC.h>
-
-#include "../../codec/xvmc/accel_xvmc.h"
-#include "xcommon.h"
-#include "../../codec/spudec/spudec.h"
-#include <unistd.h>
-
-/* picture structure */
-#define TOP_FIELD 1
-#define BOTTOM_FIELD 2
-#define FRAME_PICTURE 3
-
-/* picture coding type */
-#define I_TYPE 1
-#define P_TYPE 2
-#define B_TYPE 3
-#define D_TYPE 4
-
-/*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
-extern int Activate ( vlc_object_t * );
-extern void Deactivate ( vlc_object_t * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-#define ADAPTOR_TEXT N_("XVMC adaptor number")
-#define ADAPTOR_LONGTEXT N_( \
- "If you graphics card provides several adaptors, this option allows you " \
- "to choose which one will be used (you shouldn't have to change this).")
-
-#define DISPLAY_TEXT N_("X11 display name")
-#define DISPLAY_LONGTEXT N_( \
- "Specify the X11 hardware display you want to use. By default VLC will " \
- "use the value of the DISPLAY environment variable.")
-
-#define CHROMA_TEXT N_("XVimage chroma format")
-#define CHROMA_LONGTEXT N_( \
- "Force the XVideo renderer to use a specific chroma format instead of " \
- "trying to improve performances by using the most efficient one.")
-
-#define SHM_TEXT N_("Use shared memory")
-#define SHM_LONGTEXT N_( \
- "Use shared memory to communicate between VLC and the X server.")
-
-#define MODE_TEXT N_("Deinterlace mode")
-#define MODE_LONGTEXT N_("You can choose the default deinterlace mode")
-
-#define CROP_TEXT N_("Crop")
-#define CROP_LONGTEXT N_("You can choose the crop style to apply.")
-
-vlc_module_begin ()
- set_shortname( "XVMC" )
- add_string( "xvmc-display", NULL, NULL, DISPLAY_TEXT, DISPLAY_LONGTEXT, true )
- add_integer( "xvmc-adaptor", -1, NULL, ADAPTOR_TEXT, ADAPTOR_LONGTEXT, true )
- add_string( "xvmc-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true )
-#ifdef HAVE_SYS_SHM_H
- add_bool( "xvmc-shm", true, NULL, SHM_TEXT, SHM_LONGTEXT, true )
-#endif
- add_string( "xvmc-deinterlace-mode", "bob", NULL, MODE_TEXT, MODE_LONGTEXT, false )
- add_string( "xvmc-crop-style", "eq", NULL, CROP_TEXT, CROP_LONGTEXT, false )
-
- set_description( N_("XVMC extension video output") )
- set_capability( "video output", 10 )
- set_callbacks( Activate, Deactivate )
-vlc_module_end ()
-
-/* following functions are local */
-
-static const unsigned accel_priority[] = {
- VLC_XVMC_ACCEL_VLD,
-};
-
-#define NUM_ACCEL_PRIORITY (sizeof(accel_priority)/sizeof(accel_priority[0]))
-
-/*
- * Additional thread safety, since the plugin may decide to destroy a context
- * while it's surfaces are still active in the video-out loop.
- * When / If XvMC libs are reasonably thread-safe, the locks can be made
- * more efficient by allowing multiple threads in that do not destroy
- * the context or surfaces that may be active in other threads.
- */
-
-static void init_context_lock( context_lock_t *c )
-{
- pthread_cond_init(&c->cond,NULL);
- pthread_mutex_init(&c->mutex,NULL);
- c->num_readers = 0;
-}
-
-void free_context_lock( context_lock_t *c )
-{
- pthread_mutex_destroy(&c->mutex);
- pthread_cond_destroy(&c->cond);
-}
-
-void xvmc_context_reader_lock( context_lock_t *c )
-{
- pthread_mutex_lock(&c->mutex);
- c->num_readers++;
- pthread_mutex_unlock(&c->mutex);
-}
-
-void xvmc_context_reader_unlock( context_lock_t *c )
-{
- pthread_mutex_lock(&c->mutex);
- if (c->num_readers > 0) {
- if (--(c->num_readers) == 0) {
- pthread_cond_broadcast(&c->cond);
- }
- }
- pthread_mutex_unlock(&c->mutex);
-}
-
-void xvmc_context_writer_lock( context_lock_t *c )
-{
- pthread_mutex_lock(&c->mutex);
- while(c->num_readers) {
- pthread_cond_wait( &c->cond, &c->mutex );
- }
-}
-
-void xvmc_context_writer_unlock( context_lock_t *c )
-{
- pthread_mutex_unlock( &c->mutex );
-}
-
-void clear_xx44_palette( xx44_palette_t *p )
-{
- int i;
- uint32_t *cluts = p->cluts;
- int *ids = p->lookup_cache;
-
- i= p->size;
- while(i--)
- *cluts++ = 0;
- i = 2*OVL_PALETTE_SIZE;
- while(i--)
- *ids++ = -1;
- p->max_used=1;
-}
-
-static void init_xx44_palette( xx44_palette_t *p, unsigned num_entries )
-{
- p->size = (num_entries > XX44_PALETTE_SIZE) ?
- XX44_PALETTE_SIZE : num_entries;
-}
-
-static void dispose_xx44_palette(xx44_palette_t *p)
-{
- /* Nothing to do */
- VLC_UNUSED(p);
-}
-
-static void colorToPalette( const uint32_t *icolor, unsigned char *palette_p,
- unsigned num_xvmc_components, char *xvmc_components )
-{
- const clut_t *color = (const clut_t *) icolor;
- unsigned int i;
-
- for (i=0; i<num_xvmc_components; ++i)
- {
- switch(xvmc_components[i])
- {
- case 'V': *palette_p = color->cr; break;
- case 'U': *palette_p = color->cb; break;
- case 'Y':
- default: *palette_p = color->y; break;
- }
- palette_p++;
- }
-}
-
-
-void xx44_to_xvmc_palette( const xx44_palette_t *p,unsigned char *xvmc_palette,
- unsigned first_xx44_entry, unsigned num_xx44_entries,
- unsigned num_xvmc_components, char *xvmc_components )
-{
- unsigned int i;
- const uint32_t *cluts = p->cluts + first_xx44_entry;
-
- for( i=0; i<num_xx44_entries; ++i )
- {
- if( (cluts - p->cluts) < p->size )
- {
- colorToPalette( cluts++, xvmc_palette,
- num_xvmc_components, xvmc_components );
- xvmc_palette += num_xvmc_components;
- }
- }
-}
-
-#if 0
-static int xx44_paletteIndex( xx44_palette_t *p, int color, uint32_t clut )
-{
- unsigned int i;
- uint32_t *cluts = p->cluts;
- int tmp;
-
- if( (tmp = p->lookup_cache[color]) >= 0 )
- {
- if (cluts[tmp] == clut)
- return tmp;
- }
- for (i=0; i<p->max_used; ++i)
- {
- if (*cluts++ == clut) {
- p->lookup_cache[color] = i;
- return p->lookup_cache[color];
- }
- }
-
- if( p->max_used == (p->size -1) )
- {
- //printf("video_out: Warning! Out of xx44 palette colors!\n");
- return 1;
- }
- p->cluts[p->max_used] = clut;
- p->lookup_cache[color] = p->max_used++;
- return p->lookup_cache[color];
-}
-#endif
-
-#if 0
-static void memblend_xx44( uint8_t *mem, uint8_t val,
- size_t size, uint8_t mask )
-{
- uint8_t masked_val = val & mask;
-
-/* size_t is unsigned, therefore always positive
- if (size < 0)
- return;*/
-
- while(size--)
- {
- if( (*mem & mask) <= masked_val )
- *mem = val;
- mem++;
- }
-}
-#endif
-
-void blend_xx44( uint8_t *dst_img, subpicture_t *sub_img,
- int dst_width, int dst_height, int dst_pitch,
- xx44_palette_t *palette, int ia44 )
-{
- VLC_UNUSED(dst_img);
- VLC_UNUSED(sub_img);
- VLC_UNUSED(dst_width);
- VLC_UNUSED(dst_height);
- VLC_UNUSED(dst_pitch);
- VLC_UNUSED(palette);
- VLC_UNUSED(ia44);
-#if 0
- int src_width;
- int src_height;
- int mask;
- int x_off;
- int y_off;
- int x, y;
- uint8_t norm_pixel,clip_pixel;
- uint8_t *dst_y;
- uint8_t *dst;
- uint8_t alphamask;
- int clip_right;
- int i_len, i_color;
- uint16_t *p_source = NULL;
- if (!sub_img)
- return;
-
- src_width = sub_img->i_width;
- src_height = sub_img->i_height;
- x_off = sub_img->i_x;
- y_off = sub_img->i_y;
- alphamask = (ia44) ? 0x0F : 0xF0;
- p_source = (uint16_t *)sub_img->p_sys->p_data;
-
- dst_y = dst_img + dst_pitch*y_off + x_off;
-
- if( (x_off + sub_img->i_width) <= dst_width )
- clip_right = sub_img->i_width;
- else
- clip_right = dst_width - x_off;
-
- if ((src_height + y_off) > dst_height)
- src_height = dst_height - y_off;
-
- for (y = 0; y < src_height; y++)
- {
- mask = !( (y < sub_img->p_sys->i_y_start) ||
- (y >= sub_img->p_sys->i_y_end) );
- dst = dst_y;
-
- for (x = 0; x < src_width;)
- {
- i_color = *p_source & 0x3;
- i_len = *p_source++ >> 2;
-
- if( (i_len > 0) && ((x+i_len) <= src_width) )
- {
- /* Get the RLE part, then draw the line */
- uint32_t color = (sub_img->p_sys->pi_yuv[i_color][0] << 16) |
- (sub_img->p_sys->pi_yuv[i_color][1] << 0) |
- (sub_img->p_sys->pi_yuv[i_color][2] << 8);
-
- norm_pixel = (uint8_t)(
- (xx44_paletteIndex( palette,i_color, color ) << 4) |
- (sub_img->p_sys->pi_alpha[i_color] & 0x0F) );
- clip_pixel = (uint8_t)(
- (xx44_paletteIndex( palette,i_color + OVL_PALETTE_SIZE,
- sub_img->p_sys->pi_yuv[i_color][0] ) << 4) |
- (sub_img->p_sys->pi_alpha[i_color] & 0x0F));
-
- if( !ia44 )
- {
- norm_pixel = ((norm_pixel & 0x0F) << 4) | ((norm_pixel & 0xF0) >> 4);
- clip_pixel = ((clip_pixel & 0x0F) << 4) | ((clip_pixel & 0xF0) >> 4);
- }
- if( mask )
- {
- if( x < sub_img->p_sys->i_x_start )
- {
- if( (x + i_len) <= sub_img->p_sys->i_x_start )
- {
- memblend_xx44( dst, norm_pixel, i_len, alphamask );
- dst += i_len;
- }
- else
- {
- memblend_xx44( dst, norm_pixel,
- sub_img->p_sys->i_x_start - x,
- alphamask );
- dst += sub_img->p_sys->i_x_start - x;
- i_len -= sub_img->p_sys->i_x_start - x;
- if( i_len <= (sub_img->p_sys->i_x_end -
- sub_img->p_sys->i_x_start) )
- {
- memblend_xx44( dst, clip_pixel,
- i_len, alphamask);
- dst += i_len;
- }
- else
- {
- memblend_xx44( dst, clip_pixel,
- sub_img->p_sys->i_x_end -
- sub_img->p_sys->i_x_start,
- alphamask );
- dst += (sub_img->p_sys->i_x_end -
- sub_img->p_sys->i_x_start);
- i_len -= (sub_img->p_sys->i_x_end -
- sub_img->p_sys->i_x_start);
- memblend_xx44( dst, norm_pixel,
- i_len, alphamask );
- dst += i_len;
- }
- }
- }
- else if( x < sub_img->p_sys->i_x_end )
- {
- if( i_len <= (sub_img->p_sys->i_x_end - x) )
- {
- memblend_xx44( dst, clip_pixel, i_len, alphamask);
- dst += i_len;
- }
- else
- {
- memblend_xx44( dst, clip_pixel,
- sub_img->p_sys->i_x_end - x,
- alphamask);
- dst += (sub_img->p_sys->i_x_end - x);
- i_len -= (sub_img->p_sys->i_x_end - x);
- memblend_xx44( dst, norm_pixel, i_len, alphamask);
- dst += i_len;
- }
- }
- else
- {
- memblend_xx44( dst, norm_pixel, i_len, alphamask );
- dst += i_len;
- }
- }
- else
- {
- memblend_xx44( dst, norm_pixel, i_len, alphamask );
- dst += i_len;
- }
- }
- else
- {
- return;
- }
- x += i_len;
- }
- dst_y += dst_pitch;
- }
-#endif
-}
-
-int xxmc_xvmc_surface_valid( vout_thread_t *p_vout, XvMCSurface *surf )
-{
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
- unsigned long index = surf - handler->surfaces;
- int ret;
-
- if( index >= XVMC_MAX_SURFACES )
- return 0;
- pthread_mutex_lock(&handler->mutex);
- ret = handler->surfValid[index];
- pthread_mutex_unlock(&handler->mutex);
- return ret;
-}
-
-#if 0
-static void xxmc_xvmc_dump_subpictures( vout_thread_t *p_vout )
-{
- int i;
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
-
- for( i=0; i < XVMC_MAX_SUBPICTURES; ++i )
- {
- msg_Dbg( p_vout, "handler in use %d, valid %d",
- handler->subInUse[i],
- handler->subValid[i]);
- }
-}
-#endif
-
-XvMCSubpicture *xxmc_xvmc_alloc_subpicture( vout_thread_t *p_vout,
- XvMCContext *context, unsigned short width,
- unsigned short height, int xvimage_id )
-{
- int i;
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
- int status;
-
- pthread_mutex_lock(&handler->mutex);
- /* xxmc_xvmc_dump_subpictures(p_vout); */
- for( i=0; i<XVMC_MAX_SUBPICTURES; ++i )
- {
- if( handler->subValid[i] && !handler->subInUse[i] )
- {
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- if( XvMCGetSubpictureStatus( p_vout->p_sys->p_display,
- handler->subpictures + i,
- &status ) )
- {
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- continue;
- }
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- if( status & XVMC_DISPLAYING )
- continue;
- handler->subInUse[i] = 1;
- /* xxmc_xvmc_dump_subpictures(p_vout); */
- pthread_mutex_unlock(&handler->mutex);
- return (handler->subpictures + i);
- }
- }
- for (i=0; i<XVMC_MAX_SUBPICTURES; ++i)
- {
- if( !handler->subInUse[i] )
- {
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- if( Success != XvMCCreateSubpicture( p_vout->p_sys->p_display,
- context,
- handler->subpictures + i,
- width, height, xvimage_id ) )
- {
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- pthread_mutex_unlock( &handler->mutex );
- return NULL;
- }
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- msg_Dbg( p_vout, "video_out_xxmc: created subpicture %d", i );
- handler->subInUse[i] = 1;
- handler->subValid[i] = 1;
- pthread_mutex_unlock( &handler->mutex );
- return (handler->subpictures + i);
- }
- }
- pthread_mutex_unlock( &handler->mutex );
- return NULL;
-}
-
-void xxmc_xvmc_free_subpicture( vout_thread_t *p_vout, XvMCSubpicture *sub )
-{
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
- unsigned int index = sub - handler->subpictures;
-
- if( index >= XVMC_MAX_SUBPICTURES )
- return;
-
- pthread_mutex_lock( &handler->mutex );
- handler->subInUse[index] = 0;
- /* xxmc_xvmc_dump_subpictures(p_vout); */
- pthread_mutex_unlock( &handler->mutex );
-}
-
-static void xxmc_xvmc_surface_handler_construct( vout_thread_t *p_vout )
-{
- int i;
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
-
- pthread_mutex_init( &handler->mutex, NULL );
- for( i=0; i<XVMC_MAX_SURFACES; ++i )
- {
- handler->surfInUse[i] = 0;
- handler->surfValid[i] = 0;
- }
- for( i=0; i<XVMC_MAX_SUBPICTURES; ++i )
- {
- handler->subInUse[i] = 0;
- handler->subValid[i] = 0;
- }
-}
-
-static void xxmc_xvmc_dump_surfaces( vout_thread_t *p_vout )
-{
- int i;
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
-
- for (i=0; i<XVMC_MAX_SURFACES; ++i)
- {
- msg_Dbg(p_vout, "surfaces in use %d, valid %d;",
- handler->surfInUse[i],
- handler->surfValid[i]);
- }
-}
-
-void xxmc_xvmc_free_surface( vout_thread_t *p_vout, XvMCSurface *surf )
-{
- xvmc_surface_handler_t *handler = &p_vout->p_sys->xvmc_surf_handler;
- unsigned int index = 0;
-
- index = (surf - handler->surfaces);
-
- if (index < XVMC_MAX_SURFACES)
- {
- pthread_mutex_lock(&handler->mutex);
- msg_Dbg( p_vout,"free surface %d",index );
- handler->surfInUse[index]--;
- xxmc_xvmc_dump_surfaces(p_vout);
- pthread_mutex_unlock(&handler->mutex);
- }
-}
-
-int checkXvMCCap( vout_thread_t *p_vout )
-{
- int i_xvport = 0;
- int numSurf = 0;
- int numSub = 0;
- int i,j;
- XvMCSurfaceInfo *surfaceInfo =NULL;
- XvMCSurfaceInfo *curInfo = NULL;
- XvMCContext c;
- xvmc_capabilities_t *curCap = NULL;
- XvImageFormatValues *formatValues = NULL;
-
- i_xvport = p_vout->p_sys->i_xvport;
- p_vout->p_sys->xvmc_cap = 0;
-
- init_context_lock( &p_vout->p_sys->xvmc_lock );
- xvmc_context_writer_lock( &p_vout->p_sys->xvmc_lock );
-
- p_vout->p_sys->old_subpic = NULL;
- p_vout->p_sys->new_subpic = NULL;
- p_vout->p_sys->contextActive = 0;
- p_vout->p_sys->subImage = NULL;
- p_vout->p_sys->hwSubpictures = 0;
- p_vout->p_sys->xvmc_palette = NULL;
-
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
-
- if( !XvMCQueryExtension( p_vout->p_sys->p_display,
- &p_vout->p_sys->xvmc_eventbase,
- &p_vout->p_sys->xvmc_errbase ) )
- {
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock );
- return VLC_EGENERIC;
- }
- msg_Dbg( p_vout,"XvMC extension found" );
-
- surfaceInfo = XvMCListSurfaceTypes(p_vout->p_sys->p_display, i_xvport, &numSurf);
- if( !surfaceInfo )
- {
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock );
- return VLC_EGENERIC;
- }
-
- p_vout->p_sys->xvmc_cap =
- (xvmc_capabilities_t *) malloc( numSurf *
- sizeof(xvmc_capabilities_t) );
- if( !p_vout->p_sys->xvmc_cap )
- {
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock );
- return VLC_EGENERIC;
- }
-
- p_vout->p_sys->xvmc_num_cap = numSurf;
- curInfo = surfaceInfo;
- curCap = p_vout->p_sys->xvmc_cap;
-
- msg_Dbg( p_vout,"found %d XvMC surface types", numSurf );
-
- for( i=0; i< numSurf; ++i )
- {
- curCap->mpeg_flags = 0;
- curCap->accel_flags = 0;
- if( curInfo->chroma_format == XVMC_CHROMA_FORMAT_420 )
- {
- curCap->mpeg_flags |= ((curInfo->mc_type & XVMC_MPEG_1) ?
- VLC_XVMC_MPEG_1 : 0);
- curCap->mpeg_flags |= ((curInfo->mc_type & XVMC_MPEG_2) ?
- VLC_XVMC_MPEG_2 : 0);
- curCap->mpeg_flags |= ((curInfo->mc_type & XVMC_MPEG_4) ?
- VLC_XVMC_MPEG_4 : 0);
- curCap->accel_flags |= ((curInfo->mc_type & XVMC_VLD) ?
- VLC_XVMC_ACCEL_VLD : 0);
- curCap->accel_flags |= ((curInfo->mc_type & XVMC_IDCT) ?
- VLC_XVMC_ACCEL_IDCT : 0);
- curCap->accel_flags |= ((curInfo->mc_type & (XVMC_VLD | XVMC_IDCT)) ?
- 0 : VLC_XVMC_ACCEL_MOCOMP);
- curCap->max_width = curInfo->max_width;
- curCap->max_height = curInfo->max_height;
- curCap->sub_max_width = curInfo->subpicture_max_width;
- curCap->sub_max_height = curInfo->subpicture_max_height;
- curCap->flags = curInfo->flags;
-
- msg_Dbg (p_vout, "surface type %d: Max size: %d %d.",
- i, curCap->max_width, curCap->max_height);
- msg_Dbg (p_vout, "surface subtype %d: Max subpic size: %d %d.",
- i, curCap->sub_max_width, curCap->sub_max_height);
-
- curCap->type_id = curInfo->surface_type_id;
- formatValues = XvMCListSubpictureTypes( p_vout->p_sys->p_display,
- i_xvport,
- curCap->type_id,
- &numSub );
- curCap->subPicType.id = 0;
- if( formatValues )
- {
- msg_Dbg( p_vout, "surface type %d: found %d XvMC subpicture types",
- i, numSub);
- for( j = 0; j<numSub; ++j )
- {
- if( formatValues[j].id == FOURCC_IA44 )
- {
- curCap->subPicType = formatValues[j];
- msg_Dbg( p_vout,
- "surface type %d: detected and using "
- "IA44 subpicture type.", i );
- /* Prefer IA44 */
- break;
- }
- else if( formatValues[j].id == FOURCC_AI44 )
- {
- curCap->subPicType = formatValues[j];
- msg_Dbg( p_vout,
- "surface type %d: detected AI44 "
- "subpicture type.", i );
- }
- }
- }
- XFree(formatValues);
- curInfo++;
- curCap++;
- }
- }
- XFree(surfaceInfo);
-
- /*
- * Try to create a direct rendering context. This will fail if we are not
- * on the displaying computer or an indirect context is not available.
- */
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- curCap = p_vout->p_sys->xvmc_cap;
- if( Success == XvMCCreateContext( p_vout->p_sys->p_display, i_xvport,
- curCap->type_id,
- curCap->max_width,
- curCap->max_height,
- XVMC_DIRECT, &c ) )
- {
- msg_Dbg( p_vout, "using direct XVMC rendering context" );
- p_vout->p_sys->context_flags = XVMC_DIRECT;
- }
- else if( Success == XvMCCreateContext( p_vout->p_sys->p_display, i_xvport,
- curCap->type_id,
- curCap->max_width,
- curCap->max_height,
- 0, &c ) )
- {
- msg_Dbg( p_vout, "using default XVMC rendering context" );
- p_vout->p_sys->context_flags = 0;
- }
- else
- {
- free( p_vout->p_sys->xvmc_cap );
- p_vout->p_sys->xvmc_cap = NULL;
- msg_Err( p_vout, "use of direct XvMC context on a remote display failed"
- " falling back to XV." );
- xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock );
- return VLC_SUCCESS;
- }
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- XvMCDestroyContext( p_vout->p_sys->p_display, &c );
- xxmc_xvmc_surface_handler_construct( p_vout );
- /* p_vout->p_sys->capabilities |= VO_CAP_XXMC; */
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- init_xx44_palette( &p_vout->p_sys->palette , 0 );
- p_vout->p_sys->last_accel_request = 0xFFFFFFFF;
- xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock );
- return VLC_SUCCESS;
-}
-
-static int xxmc_setup_subpictures( vout_thread_t *p_vout,
- unsigned int width, unsigned int height )
-{
- xvmc_capabilities_t *curCap = NULL;
- XvMCSubpicture *sp = NULL;
-
- if( p_vout->p_sys->contextActive )
- {
- curCap = p_vout->p_sys->xvmc_cap + p_vout->p_sys->xvmc_cur_cap;
-
- if( (width > curCap->sub_max_width) ||
- (height > curCap->sub_max_height) )
- return VLC_EGENERIC;
-
- if( (p_vout->p_sys->xvmc_backend_subpic =
- (curCap->flags & XVMC_BACKEND_SUBPICTURE)) )
- msg_Dbg( p_vout, "using backend subpictures." );
-
- if (!p_vout->p_sys->subImage)
- {
- XLockDisplay( p_vout->p_sys->p_display );
- msg_Dbg(p_vout, "xxmc_setup_subpictures");
-#ifdef HAVE_SYS_SHM_H
- if( p_vout->p_sys->i_shm_opcode )
- {
- /* Create image using XShm extension */
- p_vout->p_sys->subImage = CreateShmImage( p_vout,
- p_vout->p_sys->p_display,
- p_vout->p_sys->i_xvport,
- curCap->subPicType.id,
- /* VLC2X11_FOURCC( p_vout->output. i_chroma ), */
- &p_vout->p_sys->subShmInfo,
- p_vout->output.i_width,
- p_vout->output.i_height );
- }
-#endif /* HAVE_SYS_SHM_H */
- XUnlockDisplay( p_vout->p_sys->p_display );
- if( !p_vout->p_sys->subImage )
- {
- msg_Dbg(p_vout, "failed allocating XvImage for supbictures" );
- return VLC_EGENERIC;
- }
- }
-
- sp = xxmc_xvmc_alloc_subpicture( p_vout, &p_vout->p_sys->context,
- width, height,
- curCap->subPicType.id );
- if( sp )
- {
- init_xx44_palette( &p_vout->p_sys->palette, sp->num_palette_entries );
- p_vout->p_sys->xvmc_palette = (char *) malloc( sp->num_palette_entries
- * sp->entry_bytes );
- xxmc_xvmc_free_subpicture( p_vout, sp);
- if( !p_vout->p_sys->xvmc_palette )
- return VLC_EGENERIC;
- p_vout->p_sys->hwSubpictures = 1;
- }
- }
- return VLC_SUCCESS;
-}
-
-static void xvmc_check_colorkey_properties( vout_thread_t *p_vout )
-{
- int num,i;
- XvAttribute *xvmc_attributes = NULL;
- Atom ap;
-
- /*
- * Determine if the context is of "Overlay" type. If so,
- * check whether we can autopaint.
- */
- p_vout->p_sys->have_xvmc_autopaint = 0;
- if( p_vout->p_sys->context_flags & XVMC_OVERLAID_SURFACE )
- {
- msg_Dbg( p_vout, "check colorkey properties" );
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_attributes = XvMCQueryAttributes( p_vout->p_sys->p_display,
- &p_vout->p_sys->context,
- &num );
- if( xvmc_attributes )
- {
- for( i = 0; i < num; ++i )
- {
- if( strncmp( "XV_AUTOPAINT_COLORKEY",
- xvmc_attributes[i].name,
- 21) == 0)
- {
- ap = XInternAtom( p_vout->p_sys->p_display,
- "XV_AUTOPAINT_COLORKEY",
- False );
- XvMCSetAttribute( p_vout->p_sys->p_display,
- &p_vout->p_sys->context,
- ap,
- 1 ); /* p_vout->p_sys->props[VO_PROP_AUTOPAINT_COLORKEY].value */
- p_vout->p_sys->have_xvmc_autopaint = 1;
- msg_Dbg( p_vout, "has xvmc autopaint" );
- }
- }
- }
- XFree( xvmc_attributes );
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- /* p_vout->p_sys->xvmc_xoverlay_type = X11OSD_COLORKEY; */
- }
-#if 0
- else
- {
- p_vout->p_sys->xvmc_xoverlay_type = X11OSD_SHAPED;
- }
-#endif
-}
-
-static void xxmc_xvmc_destroy_surfaces( vout_thread_t *p_vout )
-{
- int i;
- xvmc_surface_handler_t *handler = NULL;
-
- handler = &p_vout->p_sys->xvmc_surf_handler;
-
- pthread_mutex_lock( &handler->mutex );
- for( i = 0; i < XVMC_MAX_SURFACES; ++i )
- {
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- if( handler->surfValid[i] )
- {
- XvMCFlushSurface( p_vout->p_sys->p_display , handler->surfaces+i);
- XvMCSyncSurface( p_vout->p_sys->p_display, handler->surfaces+i );
- XvMCHideSurface( p_vout->p_sys->p_display, handler->surfaces+i );
- XvMCDestroySurface( p_vout->p_sys->p_display, handler->surfaces+i );
- }
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- handler->surfValid[i] = 0;
- }
- pthread_mutex_unlock( &handler->mutex );
-}
-
-static void xxmc_xvmc_destroy_subpictures( vout_thread_t *p_vout )
-{
- int i;
- xvmc_surface_handler_t *handler = NULL;
-
- handler = &p_vout->p_sys->xvmc_surf_handler;
-
- pthread_mutex_lock( &handler->mutex );
- for( i = 0; i < XVMC_MAX_SUBPICTURES; ++i )
- {
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- if( handler->subValid[i] )
- {
- XvMCFlushSubpicture( p_vout->p_sys->p_display , handler->subpictures+i);
- XvMCSyncSubpicture( p_vout->p_sys->p_display, handler->subpictures+i );
- XvMCDestroySubpicture( p_vout->p_sys->p_display, handler->subpictures+i );
- }
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- handler->subValid[i] = 0;
- }
- pthread_mutex_unlock( &handler->mutex );
-}
-
-static XvMCSurface *xxmc_xvmc_alloc_surface( vout_thread_t *p_vout,
- XvMCContext *context )
-{
- xvmc_surface_handler_t *handler = NULL;
- int i;
-
- handler = &p_vout->p_sys->xvmc_surf_handler;
-
- pthread_mutex_lock( &handler->mutex );
- xxmc_xvmc_dump_surfaces( p_vout );
- for( i = 0; i < XVMC_MAX_SURFACES; ++i )
- {
- if( handler->surfValid[i] && !handler->surfInUse[i] )
- {
- handler->surfInUse[i] = 1;
- msg_Dbg( p_vout, "reusing surface %d", i );
- xxmc_xvmc_dump_surfaces( p_vout );
- pthread_mutex_unlock( &handler->mutex );
- return (handler->surfaces + i);
- }
- }
- for( i = 0; i < XVMC_MAX_SURFACES; ++i )
- {
- if( !handler->surfInUse[i] )
- {
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- if( Success != XvMCCreateSurface( p_vout->p_sys->p_display,
- context,
- handler->surfaces + i) )
- {
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- pthread_mutex_unlock( &handler->mutex );
- return NULL;
- }
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
-
- msg_Dbg( p_vout, "created surface %d", i );
- handler->surfInUse[i] = 1;
- handler->surfValid[i] = 1;
- pthread_mutex_unlock( &handler->mutex );
- return (handler->surfaces + i);
- }
- }
- pthread_mutex_unlock( &handler->mutex );
- return NULL;
-}
-
-void xxmc_dispose_context( vout_thread_t *p_vout )
-{
- if( p_vout->p_sys->contextActive )
- {
- if( p_vout->p_sys->xvmc_accel &
- (VLC_XVMC_ACCEL_MOCOMP | VLC_XVMC_ACCEL_IDCT) )
- {
- xvmc_macroblocks_t *macroblocks = NULL;
-
- macroblocks = &p_vout->p_sys->macroblocks;
- XvMCDestroyMacroBlocks( p_vout->p_sys->p_display,
- ¯oblocks->macro_blocks );
- XvMCDestroyBlocks( p_vout->p_sys->p_display,
- ¯oblocks->blocks );
- }
-
- msg_Dbg( p_vout, "freeing up XvMC surfaces and subpictures" );
- free( p_vout->p_sys->xvmc_palette );
- dispose_xx44_palette( &p_vout->p_sys->palette );
- xxmc_xvmc_destroy_subpictures( p_vout );
- xxmc_xvmc_destroy_surfaces( p_vout );
-
- msg_Dbg(p_vout, "freeing up XvMC Context.");
- XLockDisplay( p_vout->p_sys->p_display );
- if( p_vout->p_sys->subImage )
- {
- XFree( p_vout->p_sys->subImage );
- p_vout->p_sys->subImage = NULL;
- }
- p_vout->p_sys->subImage = NULL;
- XUnlockDisplay( p_vout->p_sys->p_display );
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- XvMCDestroyContext( p_vout->p_sys->p_display,
- &p_vout->p_sys->context );
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- p_vout->p_sys->contextActive = 0;
- p_vout->p_sys->hwSubpictures = 0;
- p_vout->p_sys->xvmc_accel = 0;
- }
-}
-
-static int xxmc_find_context( vout_thread_t *p_vout, vlc_xxmc_t *xxmc,
- unsigned int width, unsigned int height )
-{
- unsigned int i, k;
- bool found = false;
- xvmc_capabilities_t *curCap = NULL;
- unsigned int request_mpeg_flags, request_accel_flags;
-
- request_mpeg_flags = xxmc->mpeg;
- for( k = 0; k < NUM_ACCEL_PRIORITY; ++k )
- {
- request_accel_flags = xxmc->acceleration & accel_priority[k];
- if( !request_accel_flags )
- continue;
-
- curCap = p_vout->p_sys->xvmc_cap;
- for( i =0; i < p_vout->p_sys->xvmc_num_cap; ++i )
- {
- msg_Dbg( p_vout, "surface type %d, capabilities 0x%8x 0x%8x",
- i,
- curCap->mpeg_flags,
- curCap->accel_flags );
- msg_Dbg( p_vout, "fequests: 0x%8x 0x%8x",
- request_mpeg_flags,
- request_accel_flags );
- if( ( (curCap->mpeg_flags & request_mpeg_flags) == request_mpeg_flags) &&
- (curCap->accel_flags & request_accel_flags) &&
- (width <= curCap->max_width) &&
- (height <= curCap->max_height) )
- {
- found = true;
- break;
- }
- curCap++;
- }
- if( found )
- {
- p_vout->p_sys->xvmc_cur_cap = i;
- break;
- }
- }
- if( found )
- {
- p_vout->p_sys->xvmc_accel = request_accel_flags;
- p_vout->p_sys->unsigned_intra = (curCap->flags & XVMC_INTRA_UNSIGNED);
- return 1;
- }
- p_vout->p_sys->xvmc_accel = 0;
- return 0;
-}
-
-static int xxmc_create_context( vout_thread_t *p_vout,
- unsigned int width, unsigned int height )
-{
- xvmc_capabilities_t *curCap = NULL;
-
- curCap = p_vout->p_sys->xvmc_cap + p_vout->p_sys->xvmc_cur_cap;
-
- msg_Dbg( p_vout, "creating new XvMC context %d", curCap->type_id );
-
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- if( Success == XvMCCreateContext( p_vout->p_sys->p_display,
- p_vout->p_sys->i_xvport,
- curCap->type_id,
- width,
- height,
- p_vout->p_sys->context_flags,
- &p_vout->p_sys->context ) )
- {
- p_vout->p_sys->xvmc_mpeg = curCap->mpeg_flags;
- p_vout->p_sys->xvmc_width = width;
- p_vout->p_sys->xvmc_height = height;
- p_vout->p_sys->contextActive = 1;
- }
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- return p_vout->p_sys->contextActive;
-}
-
-static void xvmc_flushsync(picture_t *picture)
-{
- vout_thread_t *p_vout = picture->p_sys->p_vout;
-
- xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock );
-
- if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) )
- {
- msg_Dbg(p_vout, "xvmc_flushsync 1 : %d", picture->p_sys->xxmc_data.result );
- picture->p_sys->xxmc_data.result = 128;
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
- return;
- }
-
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- picture->p_sys->xxmc_data.result =
- XvMCFlushSurface( p_vout->p_sys->p_display,
- picture->p_sys->xvmc_surf );
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
-}
-
-static void xvmc_flush(picture_t *picture)
-{
- vout_thread_t *p_vout = picture->p_sys->p_vout;
-
- xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock );
-
- if ( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) )
- {
- msg_Dbg(p_vout, "xvmc flush 1 : %d", picture->p_sys->xxmc_data.result );
- picture->p_sys->xxmc_data.result = 128;
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
- return;
- }
-
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- picture->p_sys->xxmc_data.result =
- XvMCFlushSurface( p_vout->p_sys->p_display,
- picture->p_sys->xvmc_surf );
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
-}
-
-static int xxmc_frame_updates( vout_thread_t *p_vout, picture_t *picture )
-{
- vlc_xxmc_t *xxmc = &picture->p_sys->xxmc_data;
-
- /*
- * If we have changed context since the surface was updated, xvmc_surf
- * is either NULL or invalid. If it is invalid. Set it to NULL.
- * Also if there are other users of this surface, deregister our use of
- * it and later try to allocate a new, fresh one.
- */
-
- if( picture->p_sys->xvmc_surf )
- {
- if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) )
- {
- xxmc_xvmc_free_surface( p_vout , picture->p_sys->xvmc_surf );
- picture->p_sys->xvmc_surf = NULL;
- }
- }
-#if 0
- if( picture->p_sys->p_image )
- {
- memset( picture->p_sys->p_image->data, 0,
- picture->p_sys->p_image->width
- * picture->p_sys->p_image->height );
- }
-#endif
- /*
- * If it is NULL create a new surface.
- */
- if( !picture->p_sys->xvmc_surf )
- {
- picture->p_sys->xvmc_surf = xxmc_xvmc_alloc_surface( p_vout,
- &p_vout->p_sys->context );
- if( !picture->p_sys->xvmc_surf )
- {
- msg_Err( p_vout, "accelerated surface allocation failed.\n"
- " You are probably out of framebuffer memory.\n"
- " Falling back to software decoding." );
- p_vout->p_sys->xvmc_accel = 0;
- xxmc_dispose_context( p_vout );
- return VLC_EGENERIC;
- }
- }
- xxmc->acceleration = p_vout->p_sys->xvmc_accel;
-
- xxmc->proc_xxmc_flush = xvmc_flush;
- xxmc->proc_xxmc_flushsync = xvmc_flushsync;
- xxmc->xvmc.proc_macro_block = NULL;
-#if 0
- frame->vo_frame.proc_duplicate_frame_data = xxmc_duplicate_frame_data;
-#endif
- xxmc->proc_xxmc_begin = xvmc_vld_frame;
- xxmc->proc_xxmc_slice = xvmc_vld_slice;
- return VLC_SUCCESS;
-}
-
-static int xxmc_xvmc_update_context( vout_thread_t *p_vout,
- picture_t *picture, uint32_t width, uint32_t height )
-{
- vlc_xxmc_t *xxmc = &picture->p_sys->xxmc_data;
-
- /*
- * Are we at all capable of doing XvMC ?
- */
- if( p_vout->p_sys->xvmc_cap == 0 )
- return VLC_EGENERIC;
-
- msg_Dbg( p_vout, "new format: need to change XvMC context. "
- "width: %d height: %d mpeg: %d acceleration: %d",
- width, height,
- xxmc->mpeg, xxmc->acceleration );
-
- if( picture->p_sys->xvmc_surf )
- xxmc_xvmc_free_surface( p_vout , picture->p_sys->xvmc_surf );
- picture->p_sys->xvmc_surf = NULL;
-
- xxmc_dispose_context( p_vout );
-
- if( xxmc_find_context( p_vout, xxmc, width, height ) )
- {
- xxmc_create_context( p_vout, width, height);
- xvmc_check_colorkey_properties( p_vout );
- xxmc_setup_subpictures(p_vout, width, height);
- }
-
- if( !p_vout->p_sys->contextActive )
- {
- msg_Dbg( p_vout, "using software decoding for this stream" );
- p_vout->p_sys->xvmc_accel = 0;
- }
- else
- {
- msg_Dbg(p_vout, "using hardware decoding for this stream." );
- }
-
- p_vout->p_sys->xvmc_mpeg = xxmc->mpeg;
- p_vout->p_sys->xvmc_width = width;
- p_vout->p_sys->xvmc_height = height;
- return p_vout->p_sys->contextActive;
-}
-
-
-void xxmc_do_update_frame( picture_t *picture, uint32_t width, uint32_t height,
- double ratio, int format, int flags)
-{
- VLC_UNUSED(ratio);
- VLC_UNUSED(flags);
- vout_thread_t *p_vout = picture->p_sys->p_vout;
- int indextime = 0;
- int status = 0;
-
- picture->p_sys->xxmc_data.decoded = 0;
- picture->p_sys->nb_display = 0;
- picture->b_force = 0;
- vlc_xxmc_t *xxmc = &picture->p_sys->xxmc_data;
-
- xvmc_context_writer_lock( &p_vout->p_sys->xvmc_lock);
- if( (p_vout->p_sys->last_accel_request != xxmc->acceleration) ||
- (p_vout->p_sys->xvmc_mpeg != xxmc->mpeg) ||
- (p_vout->p_sys->xvmc_width != width) ||
- (p_vout->p_sys->xvmc_height != height))
- {
- p_vout->p_sys->last_accel_request = xxmc->acceleration;
- xxmc_xvmc_update_context( p_vout, picture, width, height );
- }
-
- if( p_vout->p_sys->contextActive )
- xxmc_frame_updates( p_vout, picture );
-
- if( !p_vout->p_sys->contextActive )
- {
- xxmc->acceleration = 0;
- xxmc->xvmc.macroblocks = 0;
- }
- else
- {
- picture->format.i_chroma = format;
- }
- xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock);
-
- XvMCGetSurfaceStatus( p_vout->p_sys->p_display,
- picture->p_sys->xvmc_surf,
- &status );
- /* Wait a little till frame is being displayed */
- while( status & XVMC_DISPLAYING )
- {
- /* msleep(1); */
-
- XvMCGetSurfaceStatus( p_vout->p_sys->p_display,
- picture->p_sys->xvmc_surf,
- &status );
-
- indextime++;
- if( indextime > 4 )
- break;
- }
-}
-
-#if 0
-/* called xlocked */
-static void dispose_ximage( vout_thread_t *p_vout, XShmSegmentInfo *shminfo,
- XvImage *myimage )
-{
-# ifdef HAVE_SYS_SHM_H
- if( p_vout->p_sys->i_shm_opcode )
- {
- XShmDetach( p_vout->p_sys->p_display, shminfo );
- XFree( myimage );
- shmdt( shminfo->shmaddr );
- if( shminfo->shmid >= 0 )
- {
- shmctl( shminfo->shmid, IPC_RMID, 0 );
- shminfo->shmid = -1;
- }
- }
- else
-#endif
- {
- if( myimage->data )
- free(myimage->data);
- XFree (myimage);
- }
-}
-#endif
-
-void xvmc_vld_frame( picture_t *picture )
-{
- picture_sys_t *p_sys = picture->p_sys;
- vout_thread_t *p_vout = p_sys->p_vout;
- vlc_vld_frame_t *vft = &(p_sys->xxmc_data.vld_frame);
- picture_t *ff = (picture_t *) vft->forward_reference_picture;
- picture_t *bf = (picture_t *) vft->backward_reference_picture;
- XvMCMpegControl ctl;
- XvMCSurface *fs=0, *bs=0;
- XvMCQMatrix qmx;
-
- ctl.BHMV_range = vft->mv_ranges[0][0];
- ctl.BVMV_range = vft->mv_ranges[0][1];
- ctl.FHMV_range = vft->mv_ranges[1][0];
- ctl.FVMV_range = vft->mv_ranges[1][1];
- ctl.picture_structure = vft->picture_structure;
- ctl.intra_dc_precision = vft->intra_dc_precision;
- ctl.picture_coding_type = vft->picture_coding_type;
- ctl.mpeg_coding = (vft->mpeg_coding == 0) ? XVMC_MPEG_1 : XVMC_MPEG_2;
- ctl.flags = 0;
- ctl.flags |= (vft->progressive_sequence) ? XVMC_PROGRESSIVE_SEQUENCE : 0;
- ctl.flags |= (vft->scan) ? XVMC_ALTERNATE_SCAN : XVMC_ZIG_ZAG_SCAN;
- ctl.flags |= (vft->pred_dct_frame) ?
- XVMC_PRED_DCT_FRAME : XVMC_PRED_DCT_FIELD;
- ctl.flags |= (picture->b_top_field_first) ?
- XVMC_TOP_FIELD_FIRST : XVMC_BOTTOM_FIELD_FIRST;
- ctl.flags |= (vft->concealment_motion_vectors) ?
- XVMC_CONCEALMENT_MOTION_VECTORS : 0;
- ctl.flags |= (vft->q_scale_type) ? XVMC_Q_SCALE_TYPE : 0;
- ctl.flags |= (vft->intra_vlc_format) ? XVMC_INTRA_VLC_FORMAT : 0;
- ctl.flags |= (vft->second_field) ? XVMC_SECOND_FIELD : 0;
-
- if( ff )
- fs = ff->p_sys->xvmc_surf;
- if( bf )
- bs = bf->p_sys->xvmc_surf;
-
- /*
- * Below is for interlaced streams and second_field.
- */
- if( ctl.picture_coding_type == P_TYPE ) /* XVMC_P_PICTURE) */
- bs = picture->p_sys->xvmc_surf;
-
- if( (qmx.load_intra_quantiser_matrix = vft->load_intra_quantizer_matrix) )
- {
- memcpy( qmx.intra_quantiser_matrix, vft->intra_quantizer_matrix,
- sizeof(qmx.intra_quantiser_matrix) );
- }
- if( (qmx.load_non_intra_quantiser_matrix =
- vft->load_non_intra_quantizer_matrix) )
- {
- memcpy( qmx.non_intra_quantiser_matrix, vft->non_intra_quantizer_matrix,
- sizeof(qmx.non_intra_quantiser_matrix) );
- }
- qmx.load_chroma_intra_quantiser_matrix = 0;
- qmx.load_chroma_non_intra_quantiser_matrix = 0;
- xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock );
-
- if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) )
- {
- picture->p_sys->xxmc_data.result = 128;
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
- return;
- }
-
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- XvMCLoadQMatrix( p_vout->p_sys->p_display, &p_vout->p_sys->context, &qmx );
- do {
- picture->p_sys->xxmc_data.result =
- XvMCBeginSurface( p_vout->p_sys->p_display,
- &p_vout->p_sys->context,
- picture->p_sys->xvmc_surf,
- fs, bs, &ctl );
- } while( !picture->p_sys->xxmc_data.result );
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
-}
-
-void xvmc_vld_slice( picture_t *picture )
-{
- picture_sys_t *p_sys = picture->p_sys;
- vout_thread_t *p_vout = p_sys->p_vout;
-
- xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock );
- if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) )
- {
- picture->p_sys->xxmc_data.result = 128;
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
- msg_Err(p_vout, "vld slice error" );
- return;
- }
-
- XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
- picture->p_sys->xxmc_data.result =
- XvMCPutSlice2( p_vout->p_sys->p_display,
- &p_vout->p_sys->context,
- (char *)picture->p_sys->xxmc_data.slice_data,
- picture->p_sys->xxmc_data.slice_data_size,
- picture->p_sys->xxmc_data.slice_code );
-
- if( picture->p_sys->xxmc_data.result != 0 )
- msg_Err( p_vout, "vlc slice error %d",
- picture->p_sys->xxmc_data.result );
- /*
- * If CPU-saving mode is enabled, sleep after every xxmc->sleep slice. This will free
- * up the cpu while the decoder is working on the slice. The value of xxmc->sleep is calculated
- * so that the decoder thread sleeps at most 50% of the frame delay,
- * assuming a 2.6 kernel clock of 1000 Hz.
- */
- XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
-#if 0
- if( p_vout->p_sys->cpu_save_enabled )
- {
- p_vout->p_sys->cpu_saver += 1.;
- if( p_vout->p_sys->cpu_saver >= picture->p_sys->xxmc_data.sleep )
- {
- usleep(1);
- p_vout->p_sys->cpu_saver -= picture->p_sys->xxmc_data.sleep;
- }
- }
-#endif
-}