* Removed the plugins/ directory.

This commit is contained in:
Sam Hocevar 2002-08-09 22:25:36 +00:00
parent a46b30014c
commit 7ba73a88cb
434 changed files with 0 additions and 115453 deletions

View File

@ -1,5 +0,0 @@
*.a
*.so
*.so.*
*.tds
*.lib

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1 +0,0 @@
a52_SOURCES = a52.c

View File

@ -1,386 +0,0 @@
/*****************************************************************************
* a52.c: ATSC A/52 aka AC-3 decoder plugin for vlc.
* This plugin makes use of liba52 to decode A/52 audio
* (http://liba52.sf.net/).
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: a52.c,v 1.22 2002/07/31 20:56:50 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <vlc/decoder.h>
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
#ifdef HAVE_STDINT_H
# include <stdint.h> /* int16_t .. */
#elif HAVE_INTTYPES_H
# include <inttypes.h> /* int16_t .. */
#endif
#ifdef USE_A52DEC_TREE /* liba52 header file */
# include "include/a52.h"
#else
# include "a52dec/a52.h"
#endif
#include "a52.h"
#define AC3DEC_FRAME_SIZE 1536
/*
* Global lock for accessing liba52 functions.
* Currently, liba52 isn't thread-safe. So to prevent two threads from
* using liba52 at the same time, we have to set up a global lock.
* I know static variables aren't a good idea in multi-threaded programs,
* but believe me, this is the way to go.
* --Meuuh 2002-07-19
*/
static vlc_mutex_t a52_lock;
static vlc_bool_t b_liba52_initialized = 0;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int DecodeFrame ( a52_adec_thread_t * );
static int InitThread ( a52_adec_thread_t * );
static void EndThread ( a52_adec_thread_t * );
static void BitstreamCallback ( bit_stream_t *, vlc_bool_t );
static void float2s16_2 ( float *, int16_t * );
static inline int16_t convert ( int32_t );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define DYNRNG_TEXT N_("A/52 dynamic range compression")
#define DYNRNG_LONGTEXT N_( \
"Dynamic range compression makes the loud sounds softer, and the soft " \
"sounds louder, so you can more easily listen to the stream in a noisy " \
"environment without disturbing anyone. If you disable the dynamic range "\
"compression the playback will be more adapted to a movie theater or a " \
"listening room.")
vlc_module_begin();
add_category_hint( N_("Miscellaneous"), NULL );
add_bool( "a52-dynrng", 1, NULL, DYNRNG_TEXT, DYNRNG_LONGTEXT );
set_description( _("a52 ATSC A/52 aka AC-3 audio decoder module") );
set_capability( "decoder", 60 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to choose.
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
/*****************************************************************************
* RunDecoder: this function is called just after the thread is created
*****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo )
{
a52_adec_thread_t *p_a52_adec;
/* Allocate the memory needed to store the thread's structure */
p_a52_adec = (a52_adec_thread_t *)malloc( sizeof(a52_adec_thread_t) );
if (p_a52_adec == NULL)
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
}
/* FIXME */
p_a52_adec->i_channels = 2;
/*
* Initialize the thread properties
*/
p_a52_adec->p_aout_fifo = NULL;
p_a52_adec->p_fifo = p_fifo;
if( InitThread( p_a52_adec ) )
{
msg_Err( p_a52_adec->p_fifo, "could not initialize thread" );
DecoderError( p_fifo );
free( p_a52_adec );
return( -1 );
}
/* liba52 decoder thread's main loop */
while( !p_a52_adec->p_fifo->b_die && !p_a52_adec->p_fifo->b_error )
{
/* look for sync word - should be 0x0b77 */
RealignBits(&p_a52_adec->bit_stream);
while( (ShowBits( &p_a52_adec->bit_stream, 16 ) ) != 0x0b77 &&
(!p_a52_adec->p_fifo->b_die) && (!p_a52_adec->p_fifo->b_error))
{
RemoveBits( &p_a52_adec->bit_stream, 8 );
}
/* get a52 frame header */
GetChunk( &p_a52_adec->bit_stream, p_a52_adec->p_frame_buffer, 7 );
if( p_a52_adec->p_fifo->b_die ) break;
/* check if frame is valid and get frame info */
vlc_mutex_lock( &a52_lock );
p_a52_adec->frame_size = a52_syncinfo( p_a52_adec->p_frame_buffer,
&p_a52_adec->flags,
&p_a52_adec->sample_rate,
&p_a52_adec->bit_rate );
vlc_mutex_unlock( &a52_lock );
if( !p_a52_adec->frame_size )
{
msg_Warn( p_a52_adec->p_fifo, "a52_syncinfo failed" );
continue;
}
if( DecodeFrame( p_a52_adec ) && !p_a52_adec->p_fifo->b_die )
{
DecoderError( p_fifo );
free( p_a52_adec );
return( -1 );
}
}
/* If b_error is set, the decoder thread enters the error loop */
if( p_a52_adec->p_fifo->b_error )
{
DecoderError( p_a52_adec->p_fifo );
}
/* End of the liba52 decoder thread */
EndThread( p_a52_adec );
return( 0 );
}
/*****************************************************************************
* InitThread: initialize data before entering main loop
*****************************************************************************/
static int InitThread( a52_adec_thread_t * p_a52_adec )
{
/* Initialize the global lock */
vlc_mutex_lock( p_a52_adec->p_fifo->p_vlc->p_global_lock );
if ( !b_liba52_initialized )
{
vlc_mutex_init( p_a52_adec->p_fifo, &a52_lock );
b_liba52_initialized = 1;
}
vlc_mutex_unlock( p_a52_adec->p_fifo->p_vlc->p_global_lock );
/* Initialize liba52 */
vlc_mutex_lock( &a52_lock );
p_a52_adec->p_a52_state = a52_init( 0 );
vlc_mutex_unlock( &a52_lock );
if( p_a52_adec->p_a52_state == NULL )
{
msg_Err( p_a52_adec->p_fifo, "unable to initialize liba52" );
return -1;
}
p_a52_adec->b_dynrng = config_GetInt( p_a52_adec->p_fifo, "a52-dynrng" );
/* Init the BitStream */
InitBitstream( &p_a52_adec->bit_stream,
p_a52_adec->p_fifo,
BitstreamCallback, NULL );
return( 0 );
}
/*****************************************************************************
* DecodeFrame: decodes an ATSC A/52 frame.
*****************************************************************************/
static int DecodeFrame( a52_adec_thread_t * p_a52_adec )
{
sample_t sample_level = 1;
byte_t *p_buffer;
int i;
if( ( p_a52_adec->p_aout_fifo != NULL ) &&
( p_a52_adec->p_aout_fifo->i_rate != p_a52_adec->sample_rate ) )
{
/* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock (&(p_a52_adec->p_aout_fifo->data_lock));
aout_DestroyFifo (p_a52_adec->p_aout_fifo);
vlc_cond_signal (&(p_a52_adec->p_aout_fifo->data_wait));
vlc_mutex_unlock (&(p_a52_adec->p_aout_fifo->data_lock));
p_a52_adec->p_aout_fifo = NULL;
}
/* Creating the audio output fifo if not created yet */
if( p_a52_adec->p_aout_fifo == NULL )
{
p_a52_adec->p_aout_fifo = aout_CreateFifo( p_a52_adec->p_fifo,
AOUT_FIFO_PCM, p_a52_adec->i_channels,
p_a52_adec->sample_rate,
AC3DEC_FRAME_SIZE * p_a52_adec->i_channels,
NULL );
if ( p_a52_adec->p_aout_fifo == NULL )
{
return( -1 );
}
}
/* Set the Presentation Time Stamp */
CurrentPTS( &p_a52_adec->bit_stream,
&p_a52_adec->p_aout_fifo->date[
p_a52_adec->p_aout_fifo->i_end_frame],
NULL );
if( !p_a52_adec->p_aout_fifo->date[
p_a52_adec->p_aout_fifo->i_end_frame] )
{
p_a52_adec->p_aout_fifo->date[
p_a52_adec->p_aout_fifo->i_end_frame] = LAST_MDATE;
}
p_buffer = ((byte_t *)p_a52_adec->p_aout_fifo->buffer) +
( p_a52_adec->p_aout_fifo->i_end_frame * AC3DEC_FRAME_SIZE *
p_a52_adec->i_channels * sizeof(s16) );
/* FIXME */
p_a52_adec->flags = A52_STEREO | A52_ADJUST_LEVEL;
/* Get the complete frame */
GetChunk( &p_a52_adec->bit_stream, p_a52_adec->p_frame_buffer + 7,
p_a52_adec->frame_size - 7 );
if( p_a52_adec->p_fifo->b_die ) return( -1 );
/* do the actual decoding now */
vlc_mutex_lock( &a52_lock );
a52_frame( p_a52_adec->p_a52_state, p_a52_adec->p_frame_buffer,
&p_a52_adec->flags, &sample_level, 384 );
if( !p_a52_adec->b_dynrng )
a52_dynrng( p_a52_adec->p_a52_state, NULL, NULL );
for( i = 0; i < 6; i++ )
{
if( a52_block( p_a52_adec->p_a52_state ) )
{
msg_Warn( p_a52_adec->p_fifo, "a52_block failed for block %i", i );
}
float2s16_2( a52_samples( p_a52_adec->p_a52_state ),
((int16_t *)p_buffer) + i * 256 * p_a52_adec->i_channels );
}
vlc_mutex_unlock( &a52_lock );
vlc_mutex_lock( &p_a52_adec->p_aout_fifo->data_lock );
p_a52_adec->p_aout_fifo->i_end_frame =
(p_a52_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
vlc_cond_signal (&p_a52_adec->p_aout_fifo->data_wait);
vlc_mutex_unlock (&p_a52_adec->p_aout_fifo->data_lock);
return 0;
}
/*****************************************************************************
* EndThread : liba52 decoder thread destruction
*****************************************************************************/
static void EndThread (a52_adec_thread_t *p_a52_adec)
{
/* If the audio output fifo was created, we destroy it */
if (p_a52_adec->p_aout_fifo != NULL)
{
aout_DestroyFifo (p_a52_adec->p_aout_fifo);
/* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock (&(p_a52_adec->p_aout_fifo->data_lock));
vlc_cond_signal (&(p_a52_adec->p_aout_fifo->data_wait));
vlc_mutex_unlock (&(p_a52_adec->p_aout_fifo->data_lock));
}
vlc_mutex_lock( &a52_lock );
a52_free( p_a52_adec->p_a52_state );
vlc_mutex_unlock( &a52_lock );
free( p_a52_adec );
}
/*****************************************************************************
* float2s16_2 : converts floats to ints using a trick based on the IEEE
* floating-point format
*****************************************************************************/
static inline int16_t convert (int32_t i)
{
if (i > 0x43c07fff)
return 32767;
else if (i < 0x43bf8000)
return -32768;
else
return i - 0x43c00000;
}
static void float2s16_2 (float * _f, int16_t * s16)
{
int i;
int32_t * f = (int32_t *) _f;
for (i = 0; i < 256; i++) {
s16[2*i] = convert (f[i]);
s16[2*i+1] = convert (f[i+256]);
}
}
/*****************************************************************************
* BitstreamCallback: Import parameters from the new data/PES packet
*****************************************************************************
* This function is called by input's NextDataPacket.
*****************************************************************************/
static void BitstreamCallback ( bit_stream_t * p_bit_stream,
vlc_bool_t b_new_pes )
{
if( b_new_pes )
{
/* Drop special AC3 header */
/* p_bit_stream->p_byte += 3; */
}
}

View File

@ -1,59 +0,0 @@
/*****************************************************************************
* a52.h: ATSC A/52 aka AC-3 decoder plugin for vlc.
* This plugin makes use of liba52 to decode A/52 audio
* (http://liba52.sf.net/).
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: a52.h,v 1.4 2002/06/01 12:31:58 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* a52_adec_thread_t : a52 decoder thread descriptor
*****************************************************************************/
typedef struct a52_adec_thread_s
{
/*
* liba52 properties
*/
a52_state_t *p_a52_state;
int frame_size;
int flags;
int sample_rate;
int bit_rate;
vlc_bool_t b_dynrng;
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
/*
* Input properties
*/
decoder_fifo_t *p_fifo; /* stores the PES stream data */
data_packet_t *p_data;
/*
* Output properties
*/
aout_fifo_t *p_aout_fifo; /* stores the decompressed audio frames */
int i_channels;
/* temporary buffer to store the raw frame to be decoded */
u8 p_frame_buffer[3840];
} a52_adec_thread_t;

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,2 +0,0 @@
a52_system_SOURCES = a52_system.c

View File

@ -1,174 +0,0 @@
/*****************************************************************************
* a52_system.c : A52 input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: a52_system.c,v 1.3 2002/07/31 20:56:50 sam Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@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
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
#include <errno.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <sys/types.h>
/*****************************************************************************
* Constants
*****************************************************************************/
#define A52_PACKET_SIZE 16384
#define MAX_PACKETS_IN_FIFO 3
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Init ( vlc_object_t * );
static int Demux ( input_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( "A52 demuxer" );
set_capability( "demux", 150 );
set_callbacks( Init, NULL );
add_shortcut( "a52sys" );
vlc_module_end();
/*****************************************************************************
* Init: initializes ES structures
*****************************************************************************/
static int Init( vlc_object_t * p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
es_descriptor_t * p_es;
byte_t * p_peek;
/* Initialize access plug-in structures. */
if( p_input->i_mtu == 0 )
{
/* Improve speed. */
p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
}
p_input->pf_demux = Demux;
p_input->pf_rewind = NULL;
/* Have a peep at the show. */
if( input_Peek( p_input, &p_peek, 2 ) < 2 )
{
/* Stream shorter than 4 bytes... */
msg_Err( p_input, "cannot peek()" );
return( -1 );
}
if( *p_peek != 0x0b || *(p_peek + 1) != 0x77 )
{
if( *p_input->psz_demux && !strncmp( p_input->psz_demux, "a52sys", 3 ) )
{
/* User forced */
msg_Err( p_input, "this doesn't look like an a52 stream, continuing" );
}
else
{
msg_Warn( p_input, "a52 module discarded (no startcode)" );
return( -1 );
}
}
if( input_InitStream( p_input, 0 ) == -1 )
{
return( -1 );
}
input_AddProgram( p_input, 0, 0 );
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
vlc_mutex_lock( &p_input->stream.stream_lock );
p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xBD, 0 );
p_es->i_stream_id = 0xBD;
p_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
p_es->i_cat = AUDIO_ES;
input_SelectES( p_input, p_es );
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.p_selected_program->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
return( 0 );
}
/*****************************************************************************
* Demux: reads and demuxes data packets
*****************************************************************************
* Returns -1 in case of error, 0 in case of EOF, 1 otherwise
*****************************************************************************/
static int Demux( input_thread_t * p_input )
{
ssize_t i_read;
decoder_fifo_t * p_fifo =
p_input->stream.p_selected_program->pp_es[0]->p_decoder_fifo;
pes_packet_t * p_pes;
data_packet_t * p_data;
i_read = input_SplitBuffer( p_input, &p_data, A52_PACKET_SIZE );
if ( i_read <= 0 )
{
return( i_read );
}
p_pes = input_NewPES( p_input->p_method_data );
if( p_pes == NULL )
{
msg_Err( p_input, "out of memory" );
input_DeletePacket( p_input->p_method_data, p_data );
return( -1 );
}
p_pes->i_rate = p_input->stream.control.i_rate;
p_pes->p_first = p_pes->p_last = p_data;
p_pes->i_nb_data = 1;
vlc_mutex_lock( &p_fifo->data_lock );
if( p_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
{
/* Wait for the decoder. */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
vlc_mutex_unlock( &p_fifo->data_lock );
if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
|(p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_START)
| (input_ClockManageControl( p_input,
p_input->stream.p_selected_program,
(mtime_t)0 ) == PAUSE_S) )
{
msg_Warn( p_input, "synchro reinit" );
p_pes->i_pts = mdate() + DEFAULT_PTS_DELAY;
p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
}
input_DecodePES( p_fifo, p_pes );
return( 1 );
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,2 +0,0 @@
aa_SOURCES = aa.c

View File

@ -1,260 +0,0 @@
/*****************************************************************************
* vout_aa.c: Aa video output display method for testing purposes
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aa.c,v 1.9 2002/07/31 20:56:50 sam Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <aalib.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/intf.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Create ( vlc_object_t * );
static void Destroy ( vlc_object_t * );
static int Init ( vout_thread_t * );
static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * );
static void Display ( vout_thread_t *, picture_t * );
static void SetPalette ( vout_thread_t *, u16 *, u16 *, u16 * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("ASCII-art video output module") );
set_capability( "video output", 10 );
add_shortcut( "aalib" );
set_callbacks( Create, Destroy );
vlc_module_end();
/*****************************************************************************
* vout_sys_t: aa video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the aa specific properties of an output thread.
*****************************************************************************/
struct vout_sys_t
{
struct aa_context* aa_context;
aa_palette palette;
int i_width; /* width of main window */
int i_height; /* height of main window */
};
/*****************************************************************************
* Create: allocates aa video thread output method
*****************************************************************************
* This function allocates and initializes a aa vout method.
*****************************************************************************/
static int Create( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
msg_Err( p_vout, "out of memory" );
return( 1 );
}
/* Don't parse any options, but take $AAOPTS into account */
aa_parseoptions( NULL, NULL, NULL, NULL );
if (!(p_vout->p_sys->aa_context = aa_autoinit(&aa_defparams)))
{
msg_Err( p_vout, "cannot initialize aalib" );
return( 1 );
}
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = Manage;
p_vout->pf_render = Render;
p_vout->pf_display = Display;
p_vout->p_sys->i_width = aa_imgwidth(p_vout->p_sys->aa_context);
p_vout->p_sys->i_height = aa_imgheight(p_vout->p_sys->aa_context);
aa_autoinitkbd( p_vout->p_sys->aa_context, 0 );
aa_autoinitmouse( p_vout->p_sys->aa_context, AA_MOUSEPRESSMASK );
aa_hidemouse( p_vout->p_sys->aa_context );
return( 0 );
}
/*****************************************************************************
* Init: initialize aa video thread output method
*****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
int i_index;
picture_t *p_pic = NULL;
I_OUTPUTPICTURES = 0;
p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
p_vout->output.i_width = p_vout->p_sys->i_width;
p_vout->output.i_height = p_vout->p_sys->i_height;
p_vout->output.i_aspect = p_vout->p_sys->i_width
* VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
p_vout->output.pf_setpalette = SetPalette;
/* Find an empty picture slot */
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
if( p_pic == NULL )
{
return -1;
}
/* Allocate the picture */
p_pic->p->p_pixels = aa_image( p_vout->p_sys->aa_context );
p_pic->p->i_lines = p_vout->p_sys->i_height;
p_pic->p->i_pitch = p_vout->p_sys->i_width;
p_pic->p->i_pixel_pitch = 1;
p_pic->p->i_visible_pitch = p_vout->p_sys->i_width;
p_pic->i_planes = 1;
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
I_OUTPUTPICTURES++;
return 0;
}
/*****************************************************************************
* End: terminate aa video thread output method
*****************************************************************************/
static void End( vout_thread_t *p_vout )
{
;
}
/*****************************************************************************
* Destroy: destroy aa video thread output method
*****************************************************************************
* Terminate an output method created by AaCreateOutputMethod
*****************************************************************************/
static void Destroy( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
aa_close( p_vout->p_sys->aa_context );
free( p_vout->p_sys );
}
/*****************************************************************************
* Manage: handle aa events
*****************************************************************************
* This function should be called regularly by video output thread. It manages
* console events. It returns a non null value on error.
*****************************************************************************/
static int Manage( vout_thread_t *p_vout )
{
int event, x, y, b;
event = aa_getevent( p_vout->p_sys->aa_context, 0 );
switch ( event )
{
case AA_MOUSE:
aa_getmouse( p_vout->p_sys->aa_context, &x, &y, &b );
if ( b & AA_BUTTON3 )
{
intf_thread_t *p_intf;
p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF, FIND_ANYWHERE );
if( p_intf )
{
p_intf->b_menu_change = 1;
vlc_object_release( p_intf );
}
}
break;
case AA_RESIZE:
p_vout->i_changes |= VOUT_SIZE_CHANGE;
aa_resize( p_vout->p_sys->aa_context );
p_vout->p_sys->i_width = aa_imgwidth( p_vout->p_sys->aa_context );
p_vout->p_sys->i_height = aa_imgheight( p_vout->p_sys->aa_context );
break;
default:
break;
}
return( 0 );
}
/*****************************************************************************
* Render: render previously calculated output
*****************************************************************************/
static void Render( vout_thread_t *p_vout, picture_t *p_pic )
{
aa_fastrender( p_vout->p_sys->aa_context, 0, 0,
aa_imgwidth( p_vout->p_sys->aa_context ),
aa_imgheight( p_vout->p_sys->aa_context ) );
}
/*****************************************************************************
* Display: displays previously rendered output
*****************************************************************************/
static void Display( vout_thread_t *p_vout, picture_t *p_pic )
{
/* No need to do anything, the fake direct buffers stay as they are */
int i_width, i_height, i_x, i_y;
vout_PlacePicture( p_vout, p_vout->p_sys->i_width, p_vout->p_sys->i_height,
&i_x, &i_y, &i_width, &i_height );
aa_flush(p_vout->p_sys->aa_context);
}
/*****************************************************************************
* SetPalette: set the 8bpp palette
*****************************************************************************/
static void SetPalette( vout_thread_t *p_vout, u16 *red, u16 *green, u16 *blue )
{
int i;
/* Fill colors with color information */
for( i = 0; i < 256; i++ )
{
aa_setpalette( p_vout->p_sys->palette, 256 -i,
red[ i ], green[ i ], blue[ i ] );
}
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1 +0,0 @@
ac3_adec_SOURCES = ac3_adec.c ac3_decoder.c ac3_parse.c ac3_exponent.c ac3_bit_allocate.c ac3_mantissa.c ac3_rematrix.c ac3_imdct.c

View File

@ -1,384 +0,0 @@
/*****************************************************************************
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_adec.c,v 1.35 2002/07/31 20:56:50 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.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
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* memset() */
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <vlc/decoder.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h> /* getpid() */
#endif
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
#define AC3DEC_FRAME_SIZE (2*1536)
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( ac3dec_t * p_adec );
static void EndThread ( ac3dec_t * p_adec );
static void BitstreamCallback ( bit_stream_t *p_bit_stream,
vlc_bool_t b_new_pes );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
add_category_hint( N_("Miscellaneous"), NULL );
add_module ( "ac3-downmix", "downmix", NULL, NULL,
N_("AC3 downmix module"), NULL );
add_module ( "ac3-imdct", "imdct", NULL, NULL,
N_("AC3 IMDCT module"), NULL );
set_description( _("software AC3 decoder") );
set_capability( "decoder", 50 );
set_callbacks( OpenDecoder, NULL );
add_shortcut( "ac3" );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
/*****************************************************************************
* RunDecoder: this function is called just after the thread is created
*****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo )
{
ac3dec_t * p_ac3dec;
void * p_orig; /* pointer before memalign */
vlc_bool_t b_sync = 0;
/* Allocate the memory needed to store the thread's structure */
p_ac3dec = (ac3dec_t *)vlc_memalign( &p_orig, 16, sizeof(ac3dec_t) );
memset( p_ac3dec, 0, sizeof( ac3dec_t ) );
if( p_ac3dec == NULL )
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
}
/*
* Initialize the thread properties
*/
p_ac3dec->p_fifo = p_fifo;
if( InitThread( p_ac3dec ) )
{
msg_Err( p_fifo, "could not initialize thread" );
DecoderError( p_fifo );
free( p_orig );
return( -1 );
}
/* ac3 decoder thread's main loop */
/* FIXME : do we have enough room to store the decoded frames ?? */
while ((!p_ac3dec->p_fifo->b_die) && (!p_ac3dec->p_fifo->b_error))
{
s16 * buffer;
ac3_sync_info_t sync_info;
if( !b_sync )
{
int i_sync_ptr;
#define p_bit_stream (&p_ac3dec->bit_stream)
/* Go to the next PES packet and jump to sync_ptr */
do {
BitstreamNextDataPacket( p_bit_stream );
} while( !p_bit_stream->p_decoder_fifo->b_die
&& !p_bit_stream->p_decoder_fifo->b_error
&& p_bit_stream->p_data !=
p_bit_stream->p_decoder_fifo->p_first->p_first );
i_sync_ptr = *(p_bit_stream->p_byte - 2) << 8
| *(p_bit_stream->p_byte - 1);
p_bit_stream->p_byte += i_sync_ptr;
/* Empty the bit FIFO and realign the bit stream */
p_bit_stream->fifo.buffer = 0;
p_bit_stream->fifo.i_available = 0;
AlignWord( p_bit_stream );
b_sync = 1;
#undef p_bit_stream
}
if (ac3_sync_frame (p_ac3dec, &sync_info))
{
b_sync = 0;
continue;
}
if( ( p_ac3dec->p_aout_fifo != NULL ) &&
( p_ac3dec->p_aout_fifo->i_rate != sync_info.sample_rate ) )
{
/* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock (&(p_ac3dec->p_aout_fifo->data_lock));
aout_DestroyFifo (p_ac3dec->p_aout_fifo);
vlc_cond_signal (&(p_ac3dec->p_aout_fifo->data_wait));
vlc_mutex_unlock (&(p_ac3dec->p_aout_fifo->data_lock));
p_ac3dec->p_aout_fifo = NULL;
}
/* Creating the audio output fifo if not created yet */
if (p_ac3dec->p_aout_fifo == NULL ) {
p_ac3dec->p_aout_fifo =
aout_CreateFifo( p_ac3dec->p_fifo, AOUT_FIFO_PCM, 2,
sync_info.sample_rate, AC3DEC_FRAME_SIZE, NULL );
if ( p_ac3dec->p_aout_fifo == NULL )
{
p_ac3dec->p_fifo->b_error = 1;
break;
}
}
CurrentPTS( &p_ac3dec->bit_stream,
&p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->i_end_frame],
NULL );
if( !p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->i_end_frame] )
{
p_ac3dec->p_aout_fifo->date[
p_ac3dec->p_aout_fifo->i_end_frame] =
LAST_MDATE;
}
buffer = ((s16 *)p_ac3dec->p_aout_fifo->buffer) +
(p_ac3dec->p_aout_fifo->i_end_frame * AC3DEC_FRAME_SIZE);
if (ac3_decode_frame (p_ac3dec, buffer))
{
b_sync = 0;
continue;
}
vlc_mutex_lock (&p_ac3dec->p_aout_fifo->data_lock);
p_ac3dec->p_aout_fifo->i_end_frame =
(p_ac3dec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
vlc_cond_signal (&p_ac3dec->p_aout_fifo->data_wait);
vlc_mutex_unlock (&p_ac3dec->p_aout_fifo->data_lock);
RealignBits(&p_ac3dec->bit_stream);
}
/* If b_error is set, the ac3 decoder thread enters the error loop */
if (p_ac3dec->p_fifo->b_error)
{
DecoderError( p_ac3dec->p_fifo );
}
/* End of the ac3 decoder thread */
EndThread (p_ac3dec);
free( p_orig );
return( 0 );
}
/*****************************************************************************
* InitThread: initialize data before entering main loop
*****************************************************************************/
static int InitThread( ac3dec_t * p_ac3dec )
{
char *psz_name;
/*
* Choose the best downmix module
*/
p_ac3dec->p_downmix = vlc_object_create( p_ac3dec->p_fifo,
sizeof( downmix_t ) );
p_ac3dec->p_downmix->psz_object_name = "downmix";
psz_name = config_GetPsz( p_ac3dec->p_downmix, "ac3-downmix" );
p_ac3dec->p_downmix->p_module =
module_Need( p_ac3dec->p_downmix, "downmix", psz_name );
if( psz_name ) free( psz_name );
if( p_ac3dec->p_downmix->p_module == NULL )
{
msg_Err( p_ac3dec->p_fifo, "no suitable downmix module" );
vlc_object_destroy( p_ac3dec->p_downmix );
return( -1 );
}
/*
* Choose the best IMDCT module
*/
p_ac3dec->p_imdct = vlc_object_create( p_ac3dec->p_fifo,
sizeof( imdct_t ) );
#define IMDCT p_ac3dec->p_imdct
psz_name = config_GetPsz( p_ac3dec->p_fifo, "ac3-imdct" );
p_ac3dec->p_imdct->p_module =
module_Need( p_ac3dec->p_imdct, "imdct", psz_name );
if( psz_name ) free( psz_name );
if( p_ac3dec->p_imdct->p_module == NULL )
{
msg_Err( p_ac3dec->p_fifo, "no suitable IMDCT module" );
vlc_object_destroy( p_ac3dec->p_imdct );
module_Unneed( p_ac3dec->p_downmix, p_ac3dec->p_downmix->p_module );
vlc_object_destroy( p_ac3dec->p_downmix );
return( -1 );
}
/* Initialize the ac3 decoder structures */
p_ac3dec->samples = vlc_memalign( &p_ac3dec->samples_orig,
16, 6 * 256 * sizeof(float) );
IMDCT->buf = vlc_memalign( &IMDCT->buf_orig,
16, N/4 * sizeof(complex_t) );
IMDCT->delay = vlc_memalign( &IMDCT->delay_orig,
16, 6 * 256 * sizeof(float) );
IMDCT->delay1 = vlc_memalign( &IMDCT->delay1_orig,
16, 6 * 256 * sizeof(float) );
IMDCT->xcos1 = vlc_memalign( &IMDCT->xcos1_orig,
16, N/4 * sizeof(float) );
IMDCT->xsin1 = vlc_memalign( &IMDCT->xsin1_orig,
16, N/4 * sizeof(float) );
IMDCT->xcos2 = vlc_memalign( &IMDCT->xcos2_orig,
16, N/8 * sizeof(float) );
IMDCT->xsin2 = vlc_memalign( &IMDCT->xsin2_orig,
16, N/8 * sizeof(float) );
IMDCT->xcos_sin_sse = vlc_memalign( &IMDCT->xcos_sin_sse_orig,
16, 128 * 4 * sizeof(float) );
IMDCT->w_1 = vlc_memalign( &IMDCT->w_1_orig,
16, 1 * sizeof(complex_t) );
IMDCT->w_2 = vlc_memalign( &IMDCT->w_2_orig,
16, 2 * sizeof(complex_t) );
IMDCT->w_4 = vlc_memalign( &IMDCT->w_4_orig,
16, 4 * sizeof(complex_t) );
IMDCT->w_8 = vlc_memalign( &IMDCT->w_8_orig,
16, 8 * sizeof(complex_t) );
IMDCT->w_16 = vlc_memalign( &IMDCT->w_16_orig,
16, 16 * sizeof(complex_t) );
IMDCT->w_32 = vlc_memalign( &IMDCT->w_32_orig,
16, 32 * sizeof(complex_t) );
IMDCT->w_64 = vlc_memalign( &IMDCT->w_64_orig,
16, 64 * sizeof(complex_t) );
#undef IMDCT
E_( ac3_init )( p_ac3dec );
/*
* Initialize the output properties
*/
p_ac3dec->p_aout_fifo = NULL;
/*
* Bit stream
*/
InitBitstream( &p_ac3dec->bit_stream, p_ac3dec->p_fifo,
BitstreamCallback, (void *) p_ac3dec );
return( 0 );
}
/*****************************************************************************
* EndThread : ac3 decoder thread destruction
*****************************************************************************/
static void EndThread (ac3dec_t * p_ac3dec)
{
/* If the audio output fifo was created, we destroy it */
if (p_ac3dec->p_aout_fifo != NULL)
{
aout_DestroyFifo (p_ac3dec->p_aout_fifo);
/* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock (&(p_ac3dec->p_aout_fifo->data_lock));
vlc_cond_signal (&(p_ac3dec->p_aout_fifo->data_wait));
vlc_mutex_unlock (&(p_ac3dec->p_aout_fifo->data_lock));
}
/* Free allocated structures */
#define IMDCT p_ac3dec->p_imdct
free( IMDCT->w_1_orig );
free( IMDCT->w_64_orig );
free( IMDCT->w_32_orig );
free( IMDCT->w_16_orig );
free( IMDCT->w_8_orig );
free( IMDCT->w_4_orig );
free( IMDCT->w_2_orig );
free( IMDCT->xcos_sin_sse_orig );
free( IMDCT->xsin2_orig );
free( IMDCT->xcos2_orig );
free( IMDCT->xsin1_orig );
free( IMDCT->xcos1_orig );
free( IMDCT->delay1_orig );
free( IMDCT->delay_orig );
free( IMDCT->buf_orig );
#undef IMDCT
free( p_ac3dec->samples_orig );
/* Unlock the modules */
module_Unneed( p_ac3dec->p_downmix, p_ac3dec->p_downmix->p_module );
vlc_object_destroy( p_ac3dec->p_downmix );
module_Unneed( p_ac3dec->p_imdct, p_ac3dec->p_imdct->p_module );
vlc_object_destroy( p_ac3dec->p_imdct );
/* Free what's left of the decoder */
free( p_ac3dec->imdct_orig );
}
/*****************************************************************************
* BitstreamCallback: Import parameters from the new data/PES packet
*****************************************************************************
* This function is called by input's NextDataPacket.
*****************************************************************************/
static void BitstreamCallback ( bit_stream_t * p_bit_stream,
vlc_bool_t b_new_pes )
{
if( b_new_pes )
{
/* Drop special AC3 header */
/* p_bit_stream->p_byte += 3; */
}
}

View File

@ -1,409 +0,0 @@
/*****************************************************************************
* ac3_adec.h : ac3 decoder interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_adec.h,v 1.5 2002/07/31 20:56:50 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.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.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
vlc_thread_t ac3dec_CreateThread( decoder_fifo_t * p_fifo );
/**** ac3 decoder API - public ac3 decoder structures */
typedef struct ac3dec_s ac3dec_t;
typedef struct ac3_sync_info_s {
int sample_rate; /* sample rate in Hz */
int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */
} ac3_sync_info_t;
/**** ac3 decoder API - functions publically provided by the ac3 decoder ****/
int E_( ac3_init )(ac3dec_t * p_ac3dec);
int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info);
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer);
/**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/
/**** ac3 decoder internal structures ****/
/* The following structures are filled in by their corresponding parse_*
* functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
* full details on each field. Indented fields are used to denote
* conditional fields.
*/
typedef struct syncinfo_s {
/* Sync word == 0x0B77 */
/* u16 syncword; */
/* crc for the first 5/8 of the sync block */
/* u16 crc1; */
/* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
u16 fscod;
/* Frame size code */
u16 frmsizecod;
/* Information not in the AC-3 bitstream, but derived */
/* Frame size in 16 bit words */
u16 frame_size;
/* Bit rate in kilobits */
//u16 bit_rate;
} syncinfo_t;
typedef struct bsi_s {
/* Bit stream identification == 0x8 */
u16 bsid;
/* Bit stream mode */
u16 bsmod;
/* Audio coding mode */
u16 acmod;
/* If we're using the centre channel then */
/* centre mix level */
u16 cmixlev;
/* If we're using the surround channel then */
/* surround mix level */
u16 surmixlev;
/* If we're in 2/0 mode then */
/* Dolby surround mix level - NOT USED - */
u16 dsurmod;
/* Low frequency effects on */
u16 lfeon;
/* Dialogue Normalization level */
u16 dialnorm;
/* Compression exists */
u16 compre;
/* Compression level */
u16 compr;
/* Language code exists */
u16 langcode;
/* Language code */
u16 langcod;
/* Audio production info exists*/
u16 audprodie;
u16 mixlevel;
u16 roomtyp;
/* If we're in dual mono mode (acmod == 0) then extra stuff */
u16 dialnorm2;
u16 compr2e;
u16 compr2;
u16 langcod2e;
u16 langcod2;
u16 audprodi2e;
u16 mixlevel2;
u16 roomtyp2;
/* Copyright bit */
u16 copyrightb;
/* Original bit */
u16 origbs;
/* Timecode 1 exists */
u16 timecod1e;
/* Timecode 1 */
u16 timecod1;
/* Timecode 2 exists */
u16 timecod2e;
/* Timecode 2 */
u16 timecod2;
/* Additional bit stream info exists */
u16 addbsie;
/* Additional bit stream length - 1 (in bytes) */
u16 addbsil;
/* Additional bit stream information (max 64 bytes) */
u8 addbsi[64];
/* Information not in the AC-3 bitstream, but derived */
/* Number of channels (excluding LFE)
* Derived from acmod */
u16 nfchans;
} bsi_t;
/* more pain */
typedef struct audblk_s {
/* block switch bit indexed by channel num */
u16 blksw[5];
/* dither enable bit indexed by channel num */
u16 dithflag[5];
/* dynamic range gain exists */
u16 dynrnge;
/* dynamic range gain */
u16 dynrng;
/* if acmod==0 then */
/* dynamic range 2 gain exists */
u16 dynrng2e;
/* dynamic range 2 gain */
u16 dynrng2;
/* coupling strategy exists */
u16 cplstre;
/* coupling in use */
u16 cplinu;
/* channel coupled */
u16 chincpl[5];
/* if acmod==2 then */
/* Phase flags in use */
u16 phsflginu;
/* coupling begin frequency code */
u16 cplbegf;
/* coupling end frequency code */
u16 cplendf;
/* coupling band structure bits */
u16 cplbndstrc[18];
/* Do coupling co-ords exist for this channel? */
u16 cplcoe[5];
/* Master coupling co-ordinate */
u16 mstrcplco[5];
/* Per coupling band coupling co-ordinates */
u16 cplcoexp[5][18];
u16 cplcomant[5][18];
/* Phase flags for dual mono */
u16 phsflg[18];
/* Is there a rematrixing strategy */
u16 rematstr;
/* Rematrixing bits */
u16 rematflg[4];
/* Coupling exponent strategy */
u16 cplexpstr;
/* Exponent strategy for full bandwidth channels */
u16 chexpstr[5];
/* Exponent strategy for lfe channel */
u16 lfeexpstr;
/* Channel bandwidth for independent channels */
u16 chbwcod[5];
/* The absolute coupling exponent */
u16 cplabsexp;
/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
u16 cplexps[18 * 12 / 3];
/* Sanity checking constant */
u32 magic2;
/* fbw channel exponents */
u16 exps[5][252 / 3];
/* channel gain range */
u16 gainrng[5];
/* low frequency exponents */
u16 lfeexps[3];
/* Bit allocation info */
u16 baie;
/* Slow decay code */
u16 sdcycod;
/* Fast decay code */
u16 fdcycod;
/* Slow gain code */
u16 sgaincod;
/* dB per bit code */
u16 dbpbcod;
/* masking floor code */
u16 floorcod;
/* SNR offset info */
u16 snroffste;
/* coarse SNR offset */
u16 csnroffst;
/* coupling fine SNR offset */
u16 cplfsnroffst;
/* coupling fast gain code */
u16 cplfgaincod;
/* fbw fine SNR offset */
u16 fsnroffst[5];
/* fbw fast gain code */
u16 fgaincod[5];
/* lfe fine SNR offset */
u16 lfefsnroffst;
/* lfe fast gain code */
u16 lfefgaincod;
/* Coupling leak info */
u16 cplleake;
/* coupling fast leak initialization */
u16 cplfleak;
/* coupling slow leak initialization */
u16 cplsleak;
/* delta bit allocation info */
u16 deltbaie;
/* coupling delta bit allocation exists */
u16 cpldeltbae;
/* fbw delta bit allocation exists */
u16 deltbae[5];
/* number of cpl delta bit segments */
u16 cpldeltnseg;
/* coupling delta bit allocation offset */
u16 cpldeltoffst[8];
/* coupling delta bit allocation length */
u16 cpldeltlen[8];
/* coupling delta bit allocation length */
u16 cpldeltba[8];
/* number of delta bit segments */
u16 deltnseg[5];
/* fbw delta bit allocation offset */
u16 deltoffst[5][8];
/* fbw delta bit allocation length */
u16 deltlen[5][8];
/* fbw delta bit allocation length */
u16 deltba[5][8];
/* skip length exists */
u16 skiple;
/* skip length */
u16 skipl;
/* channel mantissas */
// u16 chmant[5][256];
/* coupling mantissas */
float cpl_flt[ 256 ];
// u16 cplmant[256];
/* coupling mantissas */
// u16 lfemant[7];
/* -- Information not in the bitstream, but derived thereof -- */
/* Number of coupling sub-bands */
u16 ncplsubnd;
/* Number of combined coupling sub-bands
* Derived from ncplsubnd and cplbndstrc */
u16 ncplbnd;
/* Number of exponent groups by channel
* Derived from strmant, endmant */
u16 nchgrps[5];
/* Number of coupling exponent groups
* Derived from cplbegf, cplendf, cplexpstr */
u16 ncplgrps;
/* End mantissa numbers of fbw channels */
u16 endmant[5];
/* Start and end mantissa numbers for the coupling channel */
u16 cplstrtmant;
u16 cplendmant;
/* Decoded exponent info */
u16 fbw_exp[5][256];
u16 cpl_exp[256];
u16 lfe_exp[7];
/* Bit allocation pointer results */
u16 fbw_bap[5][256];
/* FIXME?? figure out exactly how many entries there should be (253-37?) */
u16 cpl_bap[256];
u16 lfe_bap[7];
} audblk_t;
/* Everything you wanted to know about band structure */
/*
* The entire frequency domain is represented by 256 real
* floating point fourier coefficients. Only the lower 253
* coefficients are actually utilized however. We use arrays
* of 256 to be efficient in some cases.
*
* The 5 full bandwidth channels (fbw) can have their higher
* frequencies coupled together. These coupled channels then
* share their high frequency components.
*
* This coupling band is broken up into 18 sub-bands starting
* at mantissa number 37. Each sub-band is 12 bins wide.
*
* There are 50 bit allocation sub-bands which cover the entire
* frequency range. The sub-bands are of non-uniform width, and
* approximate a 1/6 octave scale.
*/
typedef struct bit_allocate_s
{
s16 psd[256];
s16 bndpsd[256];
s16 excite[256];
s16 mask[256];
s16 sdecay;
s16 fdecay;
s16 sgain;
s16 dbknee;
s16 floor;
} bit_allocate_t;
/* These store the persistent state of the packed mantissas */
typedef struct mantissa_s
{
float q_1[2];
float q_2[2];
float q_4[1];
s32 q_1_pointer;
s32 q_2_pointer;
s32 q_4_pointer;
u16 lfsr_state;
} mantissa_t;
/*****************************************************************************
* ac3dec_t : ac3 decoder thread descriptor
*****************************************************************************/
struct ac3dec_s
{
/*
* Decoder properties
*/
void * ac3_decoder_orig; /* pointer before memalign */
/*
* Thread properties
*/
vlc_thread_t thread_id; /* id for thread functions */
/*
* Input properties
*/
decoder_fifo_t * p_fifo; /* stores the PES stream data */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
int i_available;
unsigned int total_bits_read; /* temporary */
/*
* Decoder properties
*/
syncinfo_t syncinfo;
bsi_t bsi;
audblk_t audblk;
dm_par_t dm_par;
bit_allocate_t bit_allocate;
mantissa_t mantissa;
downmix_t * p_downmix;
/*
* Output properties
*/
aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */
float * samples;
void * samples_orig; /* pointer before memalign */
imdct_t * p_imdct;
void * imdct_orig; /* pointer before memalign */
};

View File

@ -1,452 +0,0 @@
/*****************************************************************************
* ac3_bit_allocate.c: ac3 allocation tables
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: ac3_bit_allocate.c,v 1.8 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.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
*****************************************************************************/
#include <string.h> /* memcpy() */
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
#include "ac3_internal.h" /* DELTA_BIT_REUSE */
static void ba_compute_psd (bit_allocate_t * p_bit, s16 start, s16 end, s16 exps[]);
static void ba_compute_excitation (bit_allocate_t * p_bit, s16 start, s16 end, s16 fgain,
s16 fastleak, s16 slowleak, s16 is_lfe);
static void ba_compute_mask (bit_allocate_t * p_bit, s16 start, s16 end, u16 fscod,
u16 deltbae, u16 deltnseg, u16 deltoffst[],
u16 deltba[], u16 deltlen[]);
static void ba_compute_bap (bit_allocate_t * p_bit, s16 start, s16 end,
s16 snroffset, s16 bap[]);
/* Misc LUTs for bit allocation process */
static const s16 slowdec[] = { 0x0f, 0x11, 0x13, 0x15 };
static const s16 fastdec[] = { 0x3f, 0x53, 0x67, 0x7b };
static const s16 slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
static const s16 dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
static const u16 floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
static const s16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
static const s16 bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
79, 85, 97, 109, 121, 133, 157, 181, 205, 229 };
static const s16 bndsz[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
6, 12, 12, 12, 12, 24, 24, 24, 24, 24 };
static const s16 masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29,
29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34,
34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 };
static const s16 latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000};
static const s16 hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0,
0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390,
0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350,
0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0,
0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420,
0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800,
0x0840, 0x0840 },
{ 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0,
0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390,
0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360,
0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0,
0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0,
0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630,
0x0840, 0x0840 },
{ 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0,
0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0,
0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390,
0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330,
0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310,
0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440,
0x0450, 0x04e0 }};
static const s16 baptab[] = { 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,
10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
static inline u16 max_value (s16 a, s16 b)
{
return (a > b ? a : b);
}
static inline u16 min_value (s16 a, s16 b)
{
return (a < b ? a : b);
}
static inline s16 logadd (s16 a, s16 b)
{
s16 c;
if ((c = a - b) >= 0) {
return (a + latab[min_value(((c) >> 1), 255)]);
} else {
return (b + latab[min_value(((-c) >> 1), 255)]);
}
}
static inline s16 calc_lowcomp (s16 a, s16 b0, s16 b1, s16 bin)
{
if (bin < 7) {
if ((b0 + 256) == b1)
a = 384;
else if (b0 > b1)
a = max_value(0, a - 64);
} else if (bin < 20) {
if ((b0 + 256) == b1)
a = 320;
else if (b0 > b1)
a = max_value(0, a - 64) ;
} else
a = max_value(0, a - 128);
return a;
}
void bit_allocate (ac3dec_t * p_ac3dec)
{
u16 i;
s16 fgain;
s16 snroffset;
s16 start;
s16 end;
s16 fastleak;
s16 slowleak;
/* Only perform bit_allocation if the exponents have changed or we
* have new sideband information */
if (p_ac3dec->audblk.chexpstr[0] == 0 && p_ac3dec->audblk.chexpstr[1] == 0 &&
p_ac3dec->audblk.chexpstr[2] == 0 && p_ac3dec->audblk.chexpstr[3] == 0 &&
p_ac3dec->audblk.chexpstr[4] == 0 && p_ac3dec->audblk.cplexpstr == 0 &&
p_ac3dec->audblk.lfeexpstr == 0 && p_ac3dec->audblk.baie == 0 &&
p_ac3dec->audblk.snroffste == 0 && p_ac3dec->audblk.deltbaie == 0)
return;
/* Do some setup before we do the bit alloc */
p_ac3dec->bit_allocate.sdecay = slowdec[p_ac3dec->audblk.sdcycod];
p_ac3dec->bit_allocate.fdecay = fastdec[p_ac3dec->audblk.fdcycod];
p_ac3dec->bit_allocate.sgain = slowgain[p_ac3dec->audblk.sgaincod];
p_ac3dec->bit_allocate.dbknee = dbpbtab[p_ac3dec->audblk.dbpbcod];
p_ac3dec->bit_allocate.floor = floortab[p_ac3dec->audblk.floorcod];
/* if all the SNR offset constants are zero then the whole block is zero */
if (!p_ac3dec->audblk.csnroffst && !p_ac3dec->audblk.fsnroffst[0] &&
!p_ac3dec->audblk.fsnroffst[1] && !p_ac3dec->audblk.fsnroffst[2] &&
!p_ac3dec->audblk.fsnroffst[3] && !p_ac3dec->audblk.fsnroffst[4] &&
!p_ac3dec->audblk.cplfsnroffst && !p_ac3dec->audblk.lfefsnroffst) {
memset(p_ac3dec->audblk.fbw_bap,0,sizeof(u16) * 256 * 5);
memset(p_ac3dec->audblk.cpl_bap,0,sizeof(u16) * 256);
memset(p_ac3dec->audblk.lfe_bap,0,sizeof(u16) * 7);
return;
}
for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
start = 0;
end = p_ac3dec->audblk.endmant[i] ;
fgain = fastgain[p_ac3dec->audblk.fgaincod[i]];
snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.fsnroffst[i]) << 2;
fastleak = 0;
slowleak = 0;
ba_compute_psd (&p_ac3dec->bit_allocate, start, end, p_ac3dec->audblk.fbw_exp[i]);
ba_compute_excitation (&p_ac3dec->bit_allocate, start, end , fgain, fastleak, slowleak, 0);
ba_compute_mask (&p_ac3dec->bit_allocate, start, end, p_ac3dec->syncinfo.fscod,
p_ac3dec->audblk.deltbae[i],
p_ac3dec->audblk.deltnseg[i],
p_ac3dec->audblk.deltoffst[i],
p_ac3dec->audblk.deltba[i],
p_ac3dec->audblk.deltlen[i]);
ba_compute_bap (&p_ac3dec->bit_allocate, start, end, snroffset, p_ac3dec->audblk.fbw_bap[i]);
}
if (p_ac3dec->audblk.cplinu) {
start = p_ac3dec->audblk.cplstrtmant;
end = p_ac3dec->audblk.cplendmant;
fgain = fastgain[p_ac3dec->audblk.cplfgaincod];
snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.cplfsnroffst) << 2 ;
fastleak = (p_ac3dec->audblk.cplfleak << 8) + 768;
slowleak = (p_ac3dec->audblk.cplsleak << 8) + 768;
ba_compute_psd (&p_ac3dec->bit_allocate, start, end, p_ac3dec->audblk.cpl_exp);
ba_compute_excitation (&p_ac3dec->bit_allocate, start, end , fgain, fastleak, slowleak, 0);
ba_compute_mask (&p_ac3dec->bit_allocate, start, end, p_ac3dec->syncinfo.fscod,
p_ac3dec->audblk.cpldeltbae,
p_ac3dec->audblk.cpldeltnseg,
p_ac3dec->audblk.cpldeltoffst,
p_ac3dec->audblk.cpldeltba,
p_ac3dec->audblk.cpldeltlen);
ba_compute_bap (&p_ac3dec->bit_allocate, start, end, snroffset, p_ac3dec->audblk.cpl_bap);
}
if (p_ac3dec->bsi.lfeon) {
start = 0;
end = 7;
fgain = fastgain[p_ac3dec->audblk.lfefgaincod];
snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.lfefsnroffst) << 2 ;
fastleak = 0;
slowleak = 0;
ba_compute_psd (&p_ac3dec->bit_allocate, start, end, p_ac3dec->audblk.lfe_exp);
ba_compute_excitation (&p_ac3dec->bit_allocate, start, end , fgain, fastleak, slowleak, 1);
ba_compute_mask (&p_ac3dec->bit_allocate, start, end, p_ac3dec->syncinfo.fscod, 2, 0, 0, 0, 0);
ba_compute_bap (&p_ac3dec->bit_allocate, start, end, snroffset, p_ac3dec->audblk.lfe_bap);
}
}
static void ba_compute_psd (bit_allocate_t * p_bit, s16 start, s16 end, s16 exps[])
{
int bin,j,k;
s16 lastbin = 0;
/* Map the exponents into dBs */
for (bin=start; bin<end; bin++) {
p_bit->psd[bin] = (3072 - (exps[bin] << 7));
}
/* Integrate the psd function over each bit allocation band */
j = start;
k = masktab[start];
do {
lastbin = min_value(bndtab[k] + bndsz[k], end);
p_bit->bndpsd[k] = p_bit->psd[j];
j++;
for (; j < lastbin; j++) {
p_bit->bndpsd[k] = logadd(p_bit->bndpsd[k],p_bit->psd[j]);
}
k++;
} while (end > lastbin);
}
static void ba_compute_excitation (bit_allocate_t * p_bit, s16 start, s16 end,
s16 fgain, s16 fastleak, s16 slowleak, s16 is_lfe)
{
int bin;
s16 bndstrt;
s16 bndend;
s16 lowcomp = 0;
s16 begin = 0;
/* Compute excitation function */
bndstrt = masktab[start];
bndend = masktab[end - 1] + 1;
if (bndstrt == 0) { /* For fbw and lfe channels */
lowcomp = calc_lowcomp(lowcomp, p_bit->bndpsd[0], p_bit->bndpsd[1], 0);
p_bit->excite[0] = p_bit->bndpsd[0] - fgain - lowcomp;
lowcomp = calc_lowcomp(lowcomp, p_bit->bndpsd[1], p_bit->bndpsd[2], 1);
p_bit->excite[1] = p_bit->bndpsd[1] - fgain - lowcomp;
begin = 7 ;
/* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
for (bin = 2; bin < 7; bin++) {
if (!(is_lfe && (bin == 6)))
lowcomp = calc_lowcomp (lowcomp, p_bit->bndpsd[bin], p_bit->bndpsd[bin+1], bin);
fastleak = p_bit->bndpsd[bin] - fgain;
slowleak = p_bit->bndpsd[bin] - p_bit->sgain;
p_bit->excite[bin] = fastleak - lowcomp;
if (!(is_lfe && (bin == 6))) {
if (p_bit->bndpsd[bin] <=
p_bit->bndpsd[bin+1])
{
begin = bin + 1 ;
break;
}
}
}
for (bin = begin; bin < min_value(bndend, 22); bin++) {
if (!(is_lfe && (bin == 6)))
lowcomp = calc_lowcomp (lowcomp, p_bit->bndpsd[bin],
p_bit->bndpsd[bin+1], bin);
fastleak -= p_bit->fdecay ;
fastleak = max_value(fastleak, p_bit->bndpsd[bin] - fgain);
slowleak -= p_bit->sdecay ;
slowleak = max_value(slowleak, p_bit->bndpsd[bin] - p_bit->sgain);
p_bit->excite[bin] = max_value(fastleak - lowcomp, slowleak);
}
begin = 22;
} else { /* For coupling channel */
begin = bndstrt;
}
for (bin = begin; bin < bndend; bin++) {
fastleak -= p_bit->fdecay;
fastleak = max_value(fastleak, p_bit->bndpsd[bin] - fgain);
slowleak -= p_bit->sdecay;
slowleak = max_value(slowleak, p_bit->bndpsd[bin] - p_bit->sgain);
p_bit->excite[bin] = max_value(fastleak, slowleak) ;
}
}
static void ba_compute_mask (bit_allocate_t * p_bit, s16 start, s16 end, u16 fscod,
u16 deltbae, u16 deltnseg, u16 deltoffst[],
u16 deltba[], u16 deltlen[])
{
int bin,k;
s16 bndstrt;
s16 bndend;
s16 delta;
bndstrt = masktab[start];
bndend = masktab[end - 1] + 1;
/* Compute the masking curve */
for (bin = bndstrt; bin < bndend; bin++) {
if (p_bit->bndpsd[bin] < p_bit->dbknee) {
p_bit->excite[bin] += ((p_bit->dbknee - p_bit->bndpsd[bin]) >> 2);
}
p_bit->mask[bin] = max_value(p_bit->excite[bin], hth[fscod][bin]);
}
/* Perform delta bit modulation if necessary */
if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) {
s16 band = 0;
s16 seg = 0;
for (seg = 0; seg < deltnseg+1; seg++) {
band += deltoffst[seg];
if (deltba[seg] >= 4) {
delta = (deltba[seg] - 3) << 7;
} else {
delta = (deltba[seg] - 4) << 7;
}
for (k = 0; k < deltlen[seg]; k++) {
p_bit->mask[band] += delta;
band++;
}
}
}
}
static void ba_compute_bap (bit_allocate_t * p_bit, s16 start, s16 end, s16 snroffset,
s16 bap[])
{
int i,j,k;
s16 lastbin = 0;
s16 address = 0;
/* Compute the bit allocation pointer for each bin */
i = start;
j = masktab[start];
do {
lastbin = min_value(bndtab[j] + bndsz[j], end);
p_bit->mask[j] -= snroffset;
p_bit->mask[j] -= p_bit->floor;
if (p_bit->mask[j] < 0)
p_bit->mask[j] = 0;
p_bit->mask[j] &= 0x1fe0;
p_bit->mask[j] += p_bit->floor;
for (k = i; k < lastbin; k++) {
address = (p_bit->psd[i] - p_bit->mask[j]) >> 5;
address = min_value(63, max_value(0, address));
bap[i] = baptab[address];
i++;
}
j++;
} while (end > lastbin);
}

View File

@ -1,129 +0,0 @@
/*****************************************************************************
* ac3_decoder.c: core ac3 decoder
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_decoder.c,v 1.9 2002/07/31 20:56:50 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
*****************************************************************************/
#include <string.h> /* memcpy() */
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h" /* ac3dec_thread_t */
#include "ac3_internal.h"
static const float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
static const float smixlev_lut[4] = { 0.707, 0.500, 0.0 , 0.500 };
int E_( ac3_init )(ac3dec_t * p_ac3dec)
{
p_ac3dec->mantissa.lfsr_state = 1; /* dither_gen initialization */
E_( imdct_init )(p_ac3dec->p_imdct) ;
return 0;
}
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
{
int i;
if (parse_bsi (p_ac3dec))
{
msg_Warn( p_ac3dec->p_fifo, "parse error" );
parse_auxdata (p_ac3dec);
return 1;
}
/* compute downmix parameters
* downmix to tow channels for now */
p_ac3dec->dm_par.clev = 0.0;
p_ac3dec->dm_par.slev = 0.0;
p_ac3dec->dm_par.unit = 1.0;
if (p_ac3dec->bsi.acmod & 0x1) /* have center */
p_ac3dec->dm_par.clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
if (p_ac3dec->bsi.acmod & 0x4) /* have surround channels */
p_ac3dec->dm_par.slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
p_ac3dec->dm_par.unit /= 1.0 + p_ac3dec->dm_par.clev + p_ac3dec->dm_par.slev;
p_ac3dec->dm_par.clev *= p_ac3dec->dm_par.unit;
p_ac3dec->dm_par.slev *= p_ac3dec->dm_par.unit;
for (i = 0; i < 6; i++) {
/* Initialize freq/time sample storage */
memset(p_ac3dec->samples, 0, sizeof(float) * 256 *
(p_ac3dec->bsi.nfchans + p_ac3dec->bsi.lfeon));
if( p_ac3dec->p_fifo->b_die || p_ac3dec->p_fifo->b_error )
{
return 1;
}
if( parse_audblk( p_ac3dec, i ) )
{
msg_Warn( p_ac3dec->p_fifo, "audioblock error" );
parse_auxdata( p_ac3dec );
return 1;
}
if( p_ac3dec->p_fifo->b_die || p_ac3dec->p_fifo->b_error )
{
return 1;
}
if( exponent_unpack( p_ac3dec ) )
{
msg_Warn( p_ac3dec->p_fifo, "unpack error" );
parse_auxdata( p_ac3dec );
return 1;
}
bit_allocate (p_ac3dec);
mantissa_unpack (p_ac3dec);
if( p_ac3dec->p_fifo->b_die || p_ac3dec->p_fifo->b_error )
{
return 1;
}
if (p_ac3dec->bsi.acmod == 0x2)
{
rematrix (p_ac3dec);
}
imdct (p_ac3dec, buffer);
buffer += 2 * 256;
}
parse_auxdata (p_ac3dec);
return 0;
}

View File

@ -1,385 +0,0 @@
/*****************************************************************************
* ac3_decoder.h : ac3 decoder interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.h,v 1.5 2002/07/31 20:56:50 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.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.
*****************************************************************************/
/**** ac3 decoder API - public ac3 decoder structures */
typedef struct ac3dec_s ac3dec_t;
typedef struct ac3_sync_info_s {
int sample_rate; /* sample rate in Hz */
int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */
} ac3_sync_info_t;
/**** ac3 decoder API - functions publically provided by the ac3 decoder ****/
int E_( ac3_init )(ac3dec_t * p_ac3dec);
int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info);
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer);
/**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/
/**** ac3 decoder internal structures ****/
/* The following structures are filled in by their corresponding parse_*
* functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
* full details on each field. Indented fields are used to denote
* conditional fields.
*/
typedef struct syncinfo_s {
/* Sync word == 0x0B77 */
/* u16 syncword; */
/* crc for the first 5/8 of the sync block */
/* u16 crc1; */
/* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
u16 fscod;
/* Frame size code */
u16 frmsizecod;
/* Information not in the AC-3 bitstream, but derived */
/* Frame size in 16 bit words */
u16 frame_size;
/* Bit rate in kilobits */
//u16 bit_rate;
} syncinfo_t;
typedef struct bsi_s {
/* Bit stream identification == 0x8 */
u16 bsid;
/* Bit stream mode */
u16 bsmod;
/* Audio coding mode */
u16 acmod;
/* If we're using the centre channel then */
/* centre mix level */
u16 cmixlev;
/* If we're using the surround channel then */
/* surround mix level */
u16 surmixlev;
/* If we're in 2/0 mode then */
/* Dolby surround mix level - NOT USED - */
u16 dsurmod;
/* Low frequency effects on */
u16 lfeon;
/* Dialogue Normalization level */
u16 dialnorm;
/* Compression exists */
u16 compre;
/* Compression level */
u16 compr;
/* Language code exists */
u16 langcode;
/* Language code */
u16 langcod;
/* Audio production info exists*/
u16 audprodie;
u16 mixlevel;
u16 roomtyp;
/* If we're in dual mono mode (acmod == 0) then extra stuff */
u16 dialnorm2;
u16 compr2e;
u16 compr2;
u16 langcod2e;
u16 langcod2;
u16 audprodi2e;
u16 mixlevel2;
u16 roomtyp2;
/* Copyright bit */
u16 copyrightb;
/* Original bit */
u16 origbs;
/* Timecode 1 exists */
u16 timecod1e;
/* Timecode 1 */
u16 timecod1;
/* Timecode 2 exists */
u16 timecod2e;
/* Timecode 2 */
u16 timecod2;
/* Additional bit stream info exists */
u16 addbsie;
/* Additional bit stream length - 1 (in bytes) */
u16 addbsil;
/* Additional bit stream information (max 64 bytes) */
u8 addbsi[64];
/* Information not in the AC-3 bitstream, but derived */
/* Number of channels (excluding LFE)
* Derived from acmod */
u16 nfchans;
} bsi_t;
/* more pain */
typedef struct audblk_s {
/* block switch bit indexed by channel num */
u16 blksw[5];
/* dither enable bit indexed by channel num */
u16 dithflag[5];
/* dynamic range gain exists */
u16 dynrnge;
/* dynamic range gain */
u16 dynrng;
/* if acmod==0 then */
/* dynamic range 2 gain exists */
u16 dynrng2e;
/* dynamic range 2 gain */
u16 dynrng2;
/* coupling strategy exists */
u16 cplstre;
/* coupling in use */
u16 cplinu;
/* channel coupled */
u16 chincpl[5];
/* if acmod==2 then */
/* Phase flags in use */
u16 phsflginu;
/* coupling begin frequency code */
u16 cplbegf;
/* coupling end frequency code */
u16 cplendf;
/* coupling band structure bits */
u16 cplbndstrc[18];
/* Do coupling co-ords exist for this channel? */
u16 cplcoe[5];
/* Master coupling co-ordinate */
u16 mstrcplco[5];
/* Per coupling band coupling co-ordinates */
u16 cplcoexp[5][18];
u16 cplcomant[5][18];
/* Phase flags for dual mono */
u16 phsflg[18];
/* Is there a rematrixing strategy */
u16 rematstr;
/* Rematrixing bits */
u16 rematflg[4];
/* Coupling exponent strategy */
u16 cplexpstr;
/* Exponent strategy for full bandwidth channels */
u16 chexpstr[5];
/* Exponent strategy for lfe channel */
u16 lfeexpstr;
/* Channel bandwidth for independent channels */
u16 chbwcod[5];
/* The absolute coupling exponent */
u16 cplabsexp;
/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
u16 cplexps[18 * 12 / 3];
/* Sanity checking constant */
u32 magic2;
/* fbw channel exponents */
u16 exps[5][252 / 3];
/* channel gain range */
u16 gainrng[5];
/* low frequency exponents */
u16 lfeexps[3];
/* Bit allocation info */
u16 baie;
/* Slow decay code */
u16 sdcycod;
/* Fast decay code */
u16 fdcycod;
/* Slow gain code */
u16 sgaincod;
/* dB per bit code */
u16 dbpbcod;
/* masking floor code */
u16 floorcod;
/* SNR offset info */
u16 snroffste;
/* coarse SNR offset */
u16 csnroffst;
/* coupling fine SNR offset */
u16 cplfsnroffst;
/* coupling fast gain code */
u16 cplfgaincod;
/* fbw fine SNR offset */
u16 fsnroffst[5];
/* fbw fast gain code */
u16 fgaincod[5];
/* lfe fine SNR offset */
u16 lfefsnroffst;
/* lfe fast gain code */
u16 lfefgaincod;
/* Coupling leak info */
u16 cplleake;
/* coupling fast leak initialization */
u16 cplfleak;
/* coupling slow leak initialization */
u16 cplsleak;
/* delta bit allocation info */
u16 deltbaie;
/* coupling delta bit allocation exists */
u16 cpldeltbae;
/* fbw delta bit allocation exists */
u16 deltbae[5];
/* number of cpl delta bit segments */
u16 cpldeltnseg;
/* coupling delta bit allocation offset */
u16 cpldeltoffst[8];
/* coupling delta bit allocation length */
u16 cpldeltlen[8];
/* coupling delta bit allocation length */
u16 cpldeltba[8];
/* number of delta bit segments */
u16 deltnseg[5];
/* fbw delta bit allocation offset */
u16 deltoffst[5][8];
/* fbw delta bit allocation length */
u16 deltlen[5][8];
/* fbw delta bit allocation length */
u16 deltba[5][8];
/* skip length exists */
u16 skiple;
/* skip length */
u16 skipl;
/* channel mantissas */
// u16 chmant[5][256];
/* coupling mantissas */
float cpl_flt[ 256 ];
// u16 cplmant[256];
/* coupling mantissas */
// u16 lfemant[7];
/* -- Information not in the bitstream, but derived thereof -- */
/* Number of coupling sub-bands */
u16 ncplsubnd;
/* Number of combined coupling sub-bands
* Derived from ncplsubnd and cplbndstrc */
u16 ncplbnd;
/* Number of exponent groups by channel
* Derived from strmant, endmant */
u16 nchgrps[5];
/* Number of coupling exponent groups
* Derived from cplbegf, cplendf, cplexpstr */
u16 ncplgrps;
/* End mantissa numbers of fbw channels */
u16 endmant[5];
/* Start and end mantissa numbers for the coupling channel */
u16 cplstrtmant;
u16 cplendmant;
/* Decoded exponent info */
u16 fbw_exp[5][256];
u16 cpl_exp[256];
u16 lfe_exp[7];
/* Bit allocation pointer results */
u16 fbw_bap[5][256];
/* FIXME?? figure out exactly how many entries there should be (253-37?) */
u16 cpl_bap[256];
u16 lfe_bap[7];
} audblk_t;
/* Everything you wanted to know about band structure */
/*
* The entire frequency domain is represented by 256 real
* floating point fourier coefficients. Only the lower 253
* coefficients are actually utilized however. We use arrays
* of 256 to be efficient in some cases.
*
* The 5 full bandwidth channels (fbw) can have their higher
* frequencies coupled together. These coupled channels then
* share their high frequency components.
*
* This coupling band is broken up into 18 sub-bands starting
* at mantissa number 37. Each sub-band is 12 bins wide.
*
* There are 50 bit allocation sub-bands which cover the entire
* frequency range. The sub-bands are of non-uniform width, and
* approximate a 1/6 octave scale.
*/
typedef struct bit_allocate_s
{
s16 psd[256];
s16 bndpsd[256];
s16 excite[256];
s16 mask[256];
s16 sdecay;
s16 fdecay;
s16 sgain;
s16 dbknee;
s16 floor;
} bit_allocate_t;
/* These store the persistent state of the packed mantissas */
typedef struct mantissa_s
{
float q_1[2];
float q_2[2];
float q_4[1];
s32 q_1_pointer;
s32 q_2_pointer;
s32 q_4_pointer;
u16 lfsr_state;
} mantissa_t;
struct ac3dec_s
{
float * samples;
void * samples_orig; /* pointer before memalign */
imdct_t * imdct;
void * imdct_orig; /* pointer before memalign */
/*
* Input properties
*/
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
int i_available;
unsigned int total_bits_read; /* temporary */
/*
* Decoder properties
*/
syncinfo_t syncinfo;
bsi_t bsi;
audblk_t audblk;
dm_par_t dm_par;
bit_allocate_t bit_allocate;
mantissa_t mantissa;
downmix_t downmix;
};

View File

@ -1,83 +0,0 @@
/*****************************************************************************
* ac3_exponent.c: ac3 exponent calculations
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_exponent.c,v 1.7 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
*****************************************************************************/
#include <string.h> /* memcpy(), memset() */
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
#include "ac3_internal.h"
#include "ac3_exponent.h"
int exponent_unpack (ac3dec_t * p_ac3dec)
{
u16 i;
for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
{
if (exp_unpack_ch (p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
p_ac3dec->audblk.nchgrps[i],
p_ac3dec->audblk.exps[i][0],
&p_ac3dec->audblk.exps[i][1],
p_ac3dec->audblk.fbw_exp[i]))
{
return 1;
}
}
if (p_ac3dec->audblk.cplinu)
{
if (exp_unpack_ch (p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
p_ac3dec->audblk.ncplgrps,
p_ac3dec->audblk.cplabsexp << 1,
p_ac3dec->audblk.cplexps,
&p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]))
{
return 1;
}
}
if (p_ac3dec->bsi.lfeon)
{
if (exp_unpack_ch (p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
2, p_ac3dec->audblk.lfeexps[0],
&p_ac3dec->audblk.lfeexps[1],
p_ac3dec->audblk.lfe_exp))
{
return 1;
}
}
return 0;
}

View File

@ -1,152 +0,0 @@
/*****************************************************************************
* ac3_exponent.h: ac3 exponent calculations
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_exponent.h,v 1.3 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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.
*****************************************************************************/
static const s16 exps_1[128] =
{
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0
};
static const s16 exps_2[128] =
{
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
0, 0, 0
};
static const s16 exps_3[128] =
{
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
0, 0, 0
};
#define UNPACK_FBW 1
#define UNPACK_CPL 2
#define UNPACK_LFE 4
static inline int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type,
u16 expstr, u16 ngrps, u16 initial_exp,
u16 exps[], u16 * dest )
{
u16 i,j;
s16 exp_acc;
if (expstr == EXP_REUSE)
{
return 0;
}
/* Handle the initial absolute exponent */
exp_acc = initial_exp;
j = 0;
/* In the case of a fbw channel then the initial absolute values is
* also an exponent */
if (type != UNPACK_CPL)
{
dest[j++] = exp_acc;
}
/* Loop through the groups and fill the dest array appropriately */
switch (expstr)
{
case EXP_D15: /* 1 */
for (i = 0; i < ngrps; i++)
{
if (exps[i] > 124)
{
msg_Err( p_ac3dec->p_fifo, "invalid exponent" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
}
break;
case EXP_D25: /* 2 */
for (i = 0; i < ngrps; i++)
{
if (exps[i] > 124)
{
msg_Err( p_ac3dec->p_fifo, "invalid exponent" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
case EXP_D45: /* 3 */
for (i = 0; i < ngrps; i++)
{
if (exps[i] > 124)
{
msg_Err( p_ac3dec->p_fifo, "invalid exponent" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
}
return 0;
}

View File

@ -1,262 +0,0 @@
/*****************************************************************************
* ac3_imdct.c: ac3 DCT
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_imdct.c,v 1.10 2002/07/31 20:56:50 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.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
*****************************************************************************/
#include <string.h> /* memcpy() */
#include <math.h>
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
void E_( imdct_init )(imdct_t * p_imdct)
{
int i;
float scale = 181.019;
p_imdct->pf_imdct_init( p_imdct );
/* More twiddle factors to turn IFFT into IMDCT */
for (i=0; i < 64; i++) {
p_imdct->xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
p_imdct->xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
}
}
void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
{
int i;
int doable = 0;
float *center=NULL, *left, *right, *left_sur, *right_sur;
float *delay_left, *delay_right;
float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
float right_tmp, left_tmp;
void (*do_imdct)(imdct_t * p_imdct, float data[], float delay[]);
/* test if dm in frequency is doable */
if (!(doable = p_ac3dec->audblk.blksw[0]))
{
do_imdct = p_ac3dec->p_imdct->pf_imdct_512;
}
else
{
do_imdct = p_ac3dec->p_imdct->pf_imdct_256;
}
/* downmix in the frequency domain if all the channels
* use the same imdct */
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{
if (doable != p_ac3dec->audblk.blksw[i])
{
do_imdct = NULL;
break;
}
}
if (do_imdct)
{
/* dowmix first and imdct */
switch(p_ac3dec->bsi.acmod)
{
case 7: /* 3/2 */
p_ac3dec->p_downmix->pf_downmix_3f_2r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
break;
case 6: /* 2/2 */
p_ac3dec->p_downmix->pf_downmix_2f_2r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
break;
case 5: /* 3/1 */
p_ac3dec->p_downmix->pf_downmix_3f_1r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
break;
case 4: /* 2/1 */
p_ac3dec->p_downmix->pf_downmix_2f_1r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
break;
case 3: /* 3/0 */
p_ac3dec->p_downmix->pf_downmix_3f_0r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
break;
case 2:
break;
default: /* 1/0 */
// if (p_ac3dec->bsi.acmod == 1)
center = p_ac3dec->samples;
// else if (p_ac3dec->bsi.acmod == 0)
// center = samples[ac3_config.dual_mono_ch_sel];
do_imdct(p_ac3dec->p_imdct, center, p_ac3dec->p_imdct->delay); /* no downmix*/
p_ac3dec->p_downmix->pf_stream_sample_1ch_to_s16 (buffer, center);
return;
break;
}
do_imdct (p_ac3dec->p_imdct, p_ac3dec->samples, p_ac3dec->p_imdct->delay);
do_imdct (p_ac3dec->p_imdct, p_ac3dec->samples+256, p_ac3dec->p_imdct->delay+256);
p_ac3dec->p_downmix->pf_stream_sample_2ch_to_s16(buffer, p_ac3dec->samples, p_ac3dec->samples+256);
} else {
/* imdct and then downmix
* delay and samples should be saved and mixed
* fprintf(stderr, "time domain downmix\n"); */
for (i=0; i<p_ac3dec->bsi.nfchans; i++)
{
if (p_ac3dec->audblk.blksw[i])
{
/* There is only a C function */
p_ac3dec->p_imdct->pf_imdct_256_nol( p_ac3dec->p_imdct,
p_ac3dec->samples+256*i, p_ac3dec->p_imdct->delay1+256*i );
}
else
{
p_ac3dec->p_imdct->pf_imdct_512_nol( p_ac3dec->p_imdct,
p_ac3dec->samples+256*i, p_ac3dec->p_imdct->delay1+256*i );
}
}
/* mix the sample, overlap */
switch(p_ac3dec->bsi.acmod)
{
case 7: /* 3/2 */
left = p_ac3dec->samples;
center = p_ac3dec->samples+256;
right = p_ac3dec->samples+2*256;
left_sur = p_ac3dec->samples+3*256;
right_sur = p_ac3dec->samples+4*256;
delay_left = p_ac3dec->p_imdct->delay;
delay_right = p_ac3dec->p_imdct->delay+256;
delay1_left = p_ac3dec->p_imdct->delay1;
delay1_center = p_ac3dec->p_imdct->delay1+256;
delay1_right = p_ac3dec->p_imdct->delay1+2*256;
delay1_sl = p_ac3dec->p_imdct->delay1+3*256;
delay1_sr = p_ac3dec->p_imdct->delay1+4*256;
for (i = 0; i < 256; i++) {
left_tmp = p_ac3dec->dm_par.unit * *left++ + p_ac3dec->dm_par.clev * *center + p_ac3dec->dm_par.slev * *left_sur++;
right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *right_sur++;
*buffer++ = (s16)(left_tmp + *delay_left);
*buffer++ = (s16)(right_tmp + *delay_right);
*delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.clev * *delay1_center + p_ac3dec->dm_par.slev * *delay1_sl++;
*delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *delay1_sr++;
}
break;
case 6: /* 2/2 */
left = p_ac3dec->samples;
right = p_ac3dec->samples+256;
left_sur = p_ac3dec->samples+2*256;
right_sur = p_ac3dec->samples+3*256;
delay_left = p_ac3dec->p_imdct->delay;
delay_right = p_ac3dec->p_imdct->delay+256;
delay1_left = p_ac3dec->p_imdct->delay1;
delay1_right = p_ac3dec->p_imdct->delay1+256;
delay1_sl = p_ac3dec->p_imdct->delay1+2*256;
delay1_sr = p_ac3dec->p_imdct->delay1+3*256;
for (i = 0; i < 256; i++) {
left_tmp = p_ac3dec->dm_par.unit * *left++ + p_ac3dec->dm_par.slev * *left_sur++;
right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.slev * *right_sur++;
*buffer++ = (s16)(left_tmp + *delay_left);
*buffer++ = (s16)(right_tmp + *delay_right);
*delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.slev * *delay1_sl++;
*delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.slev * *delay1_sr++;
}
break;
case 5: /* 3/1 */
left = p_ac3dec->samples;
center = p_ac3dec->samples+256;
right = p_ac3dec->samples+2*256;
right_sur = p_ac3dec->samples+3*256;
delay_left = p_ac3dec->p_imdct->delay;
delay_right = p_ac3dec->p_imdct->delay+256;
delay1_left = p_ac3dec->p_imdct->delay1;
delay1_center = p_ac3dec->p_imdct->delay1+256;
delay1_right = p_ac3dec->p_imdct->delay1+2*256;
delay1_sl = p_ac3dec->p_imdct->delay1+3*256;
for (i = 0; i < 256; i++) {
left_tmp = p_ac3dec->dm_par.unit * *left++ + p_ac3dec->dm_par.clev * *center - p_ac3dec->dm_par.slev * *right_sur;
right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *right_sur++;
*buffer++ = (s16)(left_tmp + *delay_left);
*buffer++ = (s16)(right_tmp + *delay_right);
*delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.clev * *delay1_center + p_ac3dec->dm_par.slev * *delay1_sl;
*delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *delay1_sl++;
}
break;
case 4: /* 2/1 */
left = p_ac3dec->samples;
right = p_ac3dec->samples+256;
right_sur = p_ac3dec->samples+2*256;
delay_left = p_ac3dec->p_imdct->delay;
delay_right = p_ac3dec->p_imdct->delay+256;
delay1_left = p_ac3dec->p_imdct->delay1;
delay1_right = p_ac3dec->p_imdct->delay1+256;
delay1_sl = p_ac3dec->p_imdct->delay1+2*256;
for (i = 0; i < 256; i++) {
left_tmp = p_ac3dec->dm_par.unit * *left++ - p_ac3dec->dm_par.slev * *right_sur;
right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.slev * *right_sur++;
*buffer++ = (s16)(left_tmp + *delay_left);
*buffer++ = (s16)(right_tmp + *delay_right);
*delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.slev * *delay1_sl;
*delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.slev * *delay1_sl++;
}
break;
case 3: /* 3/0 */
left = p_ac3dec->samples;
center = p_ac3dec->samples+256;
right = p_ac3dec->samples+2*256;
delay_left = p_ac3dec->p_imdct->delay;
delay_right = p_ac3dec->p_imdct->delay+256;
delay1_left = p_ac3dec->p_imdct->delay1;
delay1_center = p_ac3dec->p_imdct->delay1+256;
delay1_right = p_ac3dec->p_imdct->delay1+2*256;
for (i = 0; i < 256; i++) {
left_tmp = p_ac3dec->dm_par.unit * *left++ + p_ac3dec->dm_par.clev * *center;
right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++;
*buffer++ = (s16)(left_tmp + *delay_left);
*buffer++ = (s16)(right_tmp + *delay_right);
*delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.clev * *delay1_center;
*delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++;
}
break;
case 2: /* copy to output */
for (i = 0; i < 256; i++) {
*buffer++ = (s16) *(p_ac3dec->samples+i);
*buffer++ = (s16) *(p_ac3dec->samples+256+i);
}
break;
}
}
}

View File

@ -1,56 +0,0 @@
/*****************************************************************************
* ac3_internals.h: needed by the ac3 decoder
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: ac3_internal.h,v 1.3 2002/07/31 20:56:50 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.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.
*****************************************************************************/
/* Exponent strategy constants */
#define EXP_REUSE (0)
#define EXP_D15 (1)
#define EXP_D25 (2)
#define EXP_D45 (3)
/* Delta bit allocation constants */
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1)
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)
/* ac3_bit_allocate.c */
void bit_allocate (ac3dec_t *);
/* ac3_exponent.c */
int exponent_unpack (ac3dec_t *);
/* ac3_imdct.c */
void E_( imdct_init )(imdct_t * p_imdct);
void imdct (ac3dec_t * p_ac3dec, s16 * buffer);
/* ac3_mantissa.c */
void mantissa_unpack (ac3dec_t *);
/* ac3_parse.c */
int parse_bsi (ac3dec_t *);
int parse_audblk (ac3dec_t *, int);
void parse_auxdata (ac3dec_t *);
/* ac3_rematrix.c */
void rematrix (ac3dec_t *);

View File

@ -1,81 +0,0 @@
/*****************************************************************************
* ac3_mantissa.c: ac3 mantissa computation
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_mantissa.c,v 1.7 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.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
*****************************************************************************/
#include <string.h> /* memcpy() */
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
#include "ac3_mantissa.h"
void mantissa_unpack (ac3dec_t * p_ac3dec)
{
int i, j;
u32 done_cpl = 0;
p_ac3dec->mantissa.q_1_pointer = -1;
p_ac3dec->mantissa.q_2_pointer = -1;
p_ac3dec->mantissa.q_4_pointer = -1;
for (i=0; i< p_ac3dec->bsi.nfchans; i++) {
for (j=0; j < p_ac3dec->audblk.endmant[i]; j++)
*(p_ac3dec->samples+i*256+j) = coeff_get_float(p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j],
p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j]);
if (p_ac3dec->audblk.cplinu && p_ac3dec->audblk.chincpl[i] && !(done_cpl)) {
/* ncplmant is equal to 12 * ncplsubnd
* Don't dither coupling channel until channel
* separation so that interchannel noise is uncorrelated
*/
for (j=p_ac3dec->audblk.cplstrtmant; j < p_ac3dec->audblk.cplendmant; j++)
p_ac3dec->audblk.cpl_flt[j] = coeff_get_float(p_ac3dec, p_ac3dec->audblk.cpl_bap[j],
0, p_ac3dec->audblk.cpl_exp[j]);
done_cpl = 1;
}
}
/* uncouple the channel if necessary */
if (p_ac3dec->audblk.cplinu) {
for (i=0; i< p_ac3dec->bsi.nfchans; i++) {
if (p_ac3dec->audblk.chincpl[i])
uncouple_channel(p_ac3dec, i);
}
}
if (p_ac3dec->bsi.lfeon) {
/* There are always 7 mantissas for lfe, no dither for lfe */
for (j=0; j < 7 ; j++)
*(p_ac3dec->samples+5*256+j) = coeff_get_float(p_ac3dec, p_ac3dec->audblk.lfe_bap[j],
0, p_ac3dec->audblk.lfe_exp[j]);
}
}

View File

@ -1,404 +0,0 @@
/*****************************************************************************
* ac3_mantissa.h: ac3 mantissa computation
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_mantissa.h,v 1.3 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.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.
*****************************************************************************/
#define Q0 ((-2 << 15) / 3.0)
#define Q1 (0)
#define Q2 ((2 << 15) / 3.0)
static const float q_1_0[ 32 ] =
{
Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
0, 0, 0, 0, 0
};
static const float q_1_1[ 32 ] =
{
Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2,
Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2,
Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2,
0, 0, 0, 0, 0
};
static const float q_1_2[ 32 ] =
{
Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
0, 0, 0, 0, 0
};
#undef Q0
#undef Q1
#undef Q2
#define Q0 ((-4 << 15) / 5.0)
#define Q1 ((-2 << 15) / 5.0)
#define Q2 (0)
#define Q3 ((2 << 15) / 5.0)
#define Q4 ((4 << 15) / 5.0)
static const float q_2_0[ 128 ] =
{
Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
0, 0, 0
};
static const float q_2_1[ 128 ] =
{
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
0, 0, 0
};
static const float q_2_2[ 128 ] =
{
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
0, 0, 0
};
#undef Q0
#undef Q1
#undef Q2
#undef Q3
#undef Q4
#define Q0 ((-10 << 15) / 11.0)
#define Q1 ((-8 << 15) / 11.0)
#define Q2 ((-6 << 15) / 11.0)
#define Q3 ((-4 << 15) / 11.0)
#define Q4 ((-2 << 15) / 11.0)
#define Q5 (0)
#define Q6 ((2 << 15) / 11.0)
#define Q7 ((4 << 15) / 11.0)
#define Q8 ((6 << 15) / 11.0)
#define Q9 ((8 << 15) / 11.0)
#define QA ((10 << 15) / 11.0)
static const float q_4_0[ 128 ] =
{
Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3,
Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4,
Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5,
Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6,
Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7,
Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8,
Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9,
QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA,
0, 0, 0, 0, 0, 0, 0
};
static const float q_4_1[ 128 ] =
{
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
0, 0, 0, 0, 0, 0, 0
};
#undef Q0
#undef Q1
#undef Q2
#undef Q3
#undef Q4
#undef Q5
#undef Q6
#undef Q7
#undef Q8
#undef Q9
#undef QA
/* Lookup tables of 0.16 two's complement quantization values */
static const float q_3[8] =
{
(-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0,
0 , (2 << 15)/7.0, (4 << 15)/7.0,
(6 << 15)/7.0, 0
};
static const float q_5[16] =
{
(-14 << 15)/15.0, (-12 << 15)/15.0, (-10 << 15)/15.0,
(-8 << 15)/15.0, (-6 << 15)/15.0, (-4 << 15)/15.0,
(-2 << 15)/15.0, 0 , (2 << 15)/15.0,
(4 << 15)/15.0, (6 << 15)/15.0, (8 << 15)/15.0,
(10 << 15)/15.0, (12 << 15)/15.0, (14 << 15)/15.0,
0
};
/* Conversion from bap to number of bits in the mantissas
* zeros account for cases 0,1,2,4 which are special cased */
static const u16 qnttztab[16] =
{
0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
};
static const float scale_factor[25] =
{
6.10351562500000000000000000e-05,
3.05175781250000000000000000e-05,
1.52587890625000000000000000e-05,
7.62939453125000000000000000e-06,
3.81469726562500000000000000e-06,
1.90734863281250000000000000e-06,
9.53674316406250000000000000e-07,
4.76837158203125000000000000e-07,
2.38418579101562500000000000e-07,
1.19209289550781250000000000e-07,
5.96046447753906250000000000e-08,
2.98023223876953125000000000e-08,
1.49011611938476562500000000e-08,
7.45058059692382812500000000e-09,
3.72529029846191406250000000e-09,
1.86264514923095703125000000e-09,
9.31322574615478515625000000e-10,
4.65661287307739257812500000e-10,
2.32830643653869628906250000e-10,
1.16415321826934814453125000e-10,
5.82076609134674072265625000e-11,
2.91038304567337036132812500e-11,
1.45519152283668518066406250e-11,
7.27595761418342590332031250e-12,
3.63797880709171295166015625e-12,
};
static const u16 dither_lut[256] =
{
0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055,
0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb,
0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198,
0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176,
0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf,
0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321,
0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202,
0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec,
0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761,
0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f,
0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac,
0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642,
0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb,
0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415,
0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536,
0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8,
0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c,
0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2,
0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1,
0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f,
0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6,
0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58,
0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b,
0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95,
0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918,
0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6,
0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5,
0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b,
0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82,
0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c,
0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f,
0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1
};
static inline u16 dither_gen (mantissa_t * p_mantissa)
{
s16 state;
state = dither_lut[p_mantissa->lfsr_state >> 8] ^
(p_mantissa->lfsr_state << 8);
p_mantissa->lfsr_state = (u16) state;
return ( (state * (s32) (0.707106 * 256.0)) >> 8 );
}
/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */
static inline float coeff_get_float( ac3dec_t * p_ac3dec, u16 bap, u16 dithflag,
u16 exp )
{
u16 group_code = 0;
/* If the bap is 0-5 then we have special cases to take care of */
switch (bap)
{
case 0:
if (dithflag)
{
return ( dither_gen(&p_ac3dec->mantissa) * scale_factor[exp] );
}
return (0);
case 1:
if (p_ac3dec->mantissa.q_1_pointer >= 0)
{
return (p_ac3dec->mantissa.q_1[p_ac3dec->mantissa.q_1_pointer--] *
scale_factor[exp]);
}
p_ac3dec->total_bits_read += 5;
if ((group_code = GetBits (&p_ac3dec->bit_stream,5)) > 26)
{
msg_Warn( p_ac3dec->p_fifo, "invalid mantissa (1)" );
return 0;
}
p_ac3dec->mantissa.q_1[ 1 ] = q_1_1[ group_code ];
p_ac3dec->mantissa.q_1[ 0 ] = q_1_2[ group_code ];
p_ac3dec->mantissa.q_1_pointer = 1;
return (q_1_0[group_code] * scale_factor[exp]);
case 2:
if (p_ac3dec->mantissa.q_2_pointer >= 0)
{
return (p_ac3dec->mantissa.q_2[p_ac3dec->mantissa.q_2_pointer--] *
scale_factor[exp]);
}
p_ac3dec->total_bits_read += 7;
if ((group_code = GetBits (&p_ac3dec->bit_stream,7)) > 124)
{
msg_Warn( p_ac3dec->p_fifo, "invalid mantissa (2)" );
return 0;
}
p_ac3dec->mantissa.q_2[ 1 ] = q_2_1[ group_code ];
p_ac3dec->mantissa.q_2[ 0 ] = q_2_2[ group_code ];
p_ac3dec->mantissa.q_2_pointer = 1;
return (q_2_0[group_code] * scale_factor[exp]);
case 3:
p_ac3dec->total_bits_read += 3;
if ((group_code = GetBits (&p_ac3dec->bit_stream,3)) > 6)
{
msg_Warn( p_ac3dec->p_fifo, "invalid mantissa (3)" );
return 0;
}
return (q_3[group_code] * scale_factor[exp]);
case 4:
if (p_ac3dec->mantissa.q_4_pointer >= 0)
{
return (p_ac3dec->mantissa.q_4[p_ac3dec->mantissa.q_4_pointer--] *
scale_factor[exp]);
}
p_ac3dec->total_bits_read += 7;
if ((group_code = GetBits (&p_ac3dec->bit_stream,7)) > 120)
{
msg_Warn( p_ac3dec->p_fifo, "invalid mantissa (4)" );
return 0;
}
p_ac3dec->mantissa.q_4[ 0 ] = q_4_1[group_code];
p_ac3dec->mantissa.q_4_pointer = 0;
return (q_4_0[group_code] * scale_factor[exp]);
case 5:
p_ac3dec->total_bits_read += 4;
if ((group_code = GetBits (&p_ac3dec->bit_stream,4)) > 14)
{
msg_Warn( p_ac3dec->p_fifo, "invalid mantissa (5)" );
return 0;
}
return (q_5[group_code] * scale_factor[exp]);
default:
group_code = GetBits (&p_ac3dec->bit_stream,qnttztab[bap]);
group_code <<= 16 - qnttztab[bap];
p_ac3dec->total_bits_read += qnttztab[bap];
return ((s16)(group_code) * scale_factor[exp]);
}
}
/* Uncouple the coupling channel into a fbw channel */
static inline void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch)
{
u32 bnd = 0;
u32 sub_bnd = 0;
u32 i,j;
float cpl_coord = 1.0;
u32 cpl_exp_tmp;
u32 cpl_mant_tmp;
for (i = p_ac3dec->audblk.cplstrtmant; i < p_ac3dec->audblk.cplendmant;)
{
if (!p_ac3dec->audblk.cplbndstrc[sub_bnd++])
{
cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] +
3 * p_ac3dec->audblk.mstrcplco[ch];
if (p_ac3dec->audblk.cplcoexp[ch][bnd] == 15)
{
cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 11;
}
else
{
cpl_mant_tmp = ((0x10) | p_ac3dec->audblk.cplcomant[ch][bnd]) << 10;
}
cpl_coord = (cpl_mant_tmp) * scale_factor[cpl_exp_tmp] * 8.0f;
/* Invert the phase for the right channel if necessary */
if (p_ac3dec->bsi.acmod == 0x02 && p_ac3dec->audblk.phsflginu &&
ch == 1 && p_ac3dec->audblk.phsflg[bnd])
{
cpl_coord *= -1;
}
bnd++;
}
for (j=0;j < 12; j++)
{
/* Get new dither values for each channel if necessary,
* so the channels are uncorrelated */
if (p_ac3dec->audblk.dithflag[ch] && !p_ac3dec->audblk.cpl_bap[i])
{
*(p_ac3dec->samples+ch*256+i) = cpl_coord * dither_gen(&p_ac3dec->mantissa) *
scale_factor[p_ac3dec->audblk.cpl_exp[i]];
} else {
*(p_ac3dec->samples+ch*256+i) = cpl_coord * p_ac3dec->audblk.cpl_flt[i];
}
i++;
}
}
}

View File

@ -1,862 +0,0 @@
/*****************************************************************************
* ac3_parse.c: ac3 parsing procedures
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_parse.c,v 1.9 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.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
*****************************************************************************/
#include <string.h> /* memset() */
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
#include "ac3_internal.h" /* EXP_REUSE */
/* Misc LUT */
static const u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 };
struct frmsize_s
{
u16 bit_rate;
u16 frm_size[3];
};
static const struct frmsize_s frmsizecod_tbl[] =
{
{ 32 ,{64 ,69 ,96 } },
{ 32 ,{64 ,70 ,96 } },
{ 40 ,{80 ,87 ,120 } },
{ 40 ,{80 ,88 ,120 } },
{ 48 ,{96 ,104 ,144 } },
{ 48 ,{96 ,105 ,144 } },
{ 56 ,{112 ,121 ,168 } },
{ 56 ,{112 ,122 ,168 } },
{ 64 ,{128 ,139 ,192 } },
{ 64 ,{128 ,140 ,192 } },
{ 80 ,{160 ,174 ,240 } },
{ 80 ,{160 ,175 ,240 } },
{ 96 ,{192 ,208 ,288 } },
{ 96 ,{192 ,209 ,288 } },
{ 112 ,{224 ,243 ,336 } },
{ 112 ,{224 ,244 ,336 } },
{ 128 ,{256 ,278 ,384 } },
{ 128 ,{256 ,279 ,384 } },
{ 160 ,{320 ,348 ,480 } },
{ 160 ,{320 ,349 ,480 } },
{ 192 ,{384 ,417 ,576 } },
{ 192 ,{384 ,418 ,576 } },
{ 224 ,{448 ,487 ,672 } },
{ 224 ,{448 ,488 ,672 } },
{ 256 ,{512 ,557 ,768 } },
{ 256 ,{512 ,558 ,768 } },
{ 320 ,{640 ,696 ,960 } },
{ 320 ,{640 ,697 ,960 } },
{ 384 ,{768 ,835 ,1152 } },
{ 384 ,{768 ,836 ,1152 } },
{ 448 ,{896 ,975 ,1344 } },
{ 448 ,{896 ,976 ,1344 } },
{ 512 ,{1024 ,1114 ,1536 } },
{ 512 ,{1024 ,1115 ,1536 } },
{ 576 ,{1152 ,1253 ,1728 } },
{ 576 ,{1152 ,1254 ,1728 } },
{ 640 ,{1280 ,1393 ,1920 } },
{ 640 ,{1280 ,1394 ,1920 } }};
static const int fscod_tbl[] = {48000, 44100, 32000};
/* Some internal functions */
static void parse_bsi_stats (ac3dec_t * p_ac3dec);
static void parse_audblk_stats (ac3dec_t * p_ac3dec);
/* Parse a syncinfo structure */
int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info)
{
p_ac3dec->total_bits_read = 0;
p_ac3dec->i_available = 0;
/* sync word - should be 0x0b77 */
RealignBits(&p_ac3dec->bit_stream);
while( (ShowBits (&p_ac3dec->bit_stream,16)) != 0x0b77 &&
(!p_ac3dec->p_fifo->b_die) && (!p_ac3dec->p_fifo->b_error))
{
RemoveBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
RemoveBits (&p_ac3dec->bit_stream,16);
p_ac3dec->total_bits_read += 16;
/* Get crc1 - we don't actually use this data though */
GetBits (&p_ac3dec->bit_stream,16);
/* Get the sampling rate */
p_ac3dec->syncinfo.fscod = GetBits (&p_ac3dec->bit_stream,2);
if (p_ac3dec->syncinfo.fscod >= 3)
{
p_ac3dec->total_bits_read += 34;
return 1;
}
/* Get the frame size code */
p_ac3dec->syncinfo.frmsizecod = GetBits (&p_ac3dec->bit_stream,6);
p_ac3dec->total_bits_read += 40;
if (p_ac3dec->syncinfo.frmsizecod >= 38)
{
return 1;
}
p_sync_info->bit_rate = frmsizecod_tbl[p_ac3dec->syncinfo.frmsizecod].bit_rate;
p_ac3dec->syncinfo.frame_size = frmsizecod_tbl[p_ac3dec->syncinfo.frmsizecod].frm_size[p_ac3dec->syncinfo.fscod];
p_sync_info->frame_size = 2 * p_ac3dec->syncinfo.frame_size;
p_sync_info->sample_rate = fscod_tbl[p_ac3dec->syncinfo.fscod];
return 0;
}
/*
* This routine fills a bsi struct from the AC3 stream
*/
int parse_bsi (ac3dec_t * p_ac3dec)
{
/* Check the AC-3 version number */
p_ac3dec->bsi.bsid = GetBits (&p_ac3dec->bit_stream,5);
if (p_ac3dec->bsi.bsid > 8)
{
return 1;
}
/* Get the audio service provided by the stream */
p_ac3dec->bsi.bsmod = GetBits (&p_ac3dec->bit_stream,3);
/* Get the audio coding mode (ie how many channels)*/
p_ac3dec->bsi.acmod = GetBits (&p_ac3dec->bit_stream,3);
/* Predecode the number of full bandwidth channels as we use this
* number a lot */
p_ac3dec->bsi.nfchans = nfchans[p_ac3dec->bsi.acmod];
/* If it is in use, get the centre channel mix level */
if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
{
p_ac3dec->bsi.cmixlev = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
}
/* If it is in use, get the surround channel mix level */
if (p_ac3dec->bsi.acmod & 0x4)
{
p_ac3dec->bsi.surmixlev = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
}
/* Get the dolby surround mode if in 2/0 mode */
if (p_ac3dec->bsi.acmod == 0x2)
{
p_ac3dec->bsi.dsurmod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
}
/* Is the low frequency effects channel on? */
p_ac3dec->bsi.lfeon = GetBits (&p_ac3dec->bit_stream,1);
/* Get the dialogue normalization level */
p_ac3dec->bsi.dialnorm = GetBits (&p_ac3dec->bit_stream,5);
/* Does compression gain exist? */
if ((p_ac3dec->bsi.compre = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get compression gain */
p_ac3dec->bsi.compr = GetBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
/* Does language code exist? */
if ((p_ac3dec->bsi.langcode = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get langauge code */
p_ac3dec->bsi.langcod = GetBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
/* Does audio production info exist? */
if ((p_ac3dec->bsi.audprodie = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get mix level */
p_ac3dec->bsi.mixlevel = GetBits (&p_ac3dec->bit_stream,5);
/* Get room type */
p_ac3dec->bsi.roomtyp = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 7;
}
/* If we're in dual mono mode then get some extra info */
if (p_ac3dec->bsi.acmod == 0)
{
/* Get the dialogue normalization level two */
p_ac3dec->bsi.dialnorm2 = GetBits (&p_ac3dec->bit_stream,5);
/* Does compression gain two exist? */
if ((p_ac3dec->bsi.compr2e = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get compression gain two */
p_ac3dec->bsi.compr2 = GetBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
/* Does language code two exist? */
if ((p_ac3dec->bsi.langcod2e = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get langauge code two */
p_ac3dec->bsi.langcod2 = GetBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
/* Does audio production info two exist? */
if ((p_ac3dec->bsi.audprodi2e = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get mix level two */
p_ac3dec->bsi.mixlevel2 = GetBits (&p_ac3dec->bit_stream,5);
/* Get room type two */
p_ac3dec->bsi.roomtyp2 = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 7;
}
p_ac3dec->total_bits_read += 8;
}
/* Get the copyright bit */
p_ac3dec->bsi.copyrightb = GetBits (&p_ac3dec->bit_stream,1);
/* Get the original bit */
p_ac3dec->bsi.origbs = GetBits (&p_ac3dec->bit_stream,1);
/* Does timecode one exist? */
if ((p_ac3dec->bsi.timecod1e = GetBits (&p_ac3dec->bit_stream,1)))
{
p_ac3dec->bsi.timecod1 = GetBits (&p_ac3dec->bit_stream,14);
p_ac3dec->total_bits_read += 14;
}
/* Does timecode two exist? */
if ((p_ac3dec->bsi.timecod2e = GetBits (&p_ac3dec->bit_stream,1)))
{
p_ac3dec->bsi.timecod2 = GetBits (&p_ac3dec->bit_stream,14);
p_ac3dec->total_bits_read += 14;
}
/* Does addition info exist? */
if ((p_ac3dec->bsi.addbsie = GetBits (&p_ac3dec->bit_stream,1)))
{
u32 i;
/* Get how much info is there */
p_ac3dec->bsi.addbsil = GetBits (&p_ac3dec->bit_stream,6);
/* Get the additional info */
for (i=0;i<(p_ac3dec->bsi.addbsil + 1);i++)
{
p_ac3dec->bsi.addbsi[i] = GetBits (&p_ac3dec->bit_stream,8);
}
p_ac3dec->total_bits_read += 6 + 8 * (p_ac3dec->bsi.addbsil + 1);
}
p_ac3dec->total_bits_read += 25;
parse_bsi_stats (p_ac3dec);
return 0;
}
/* More pain inducing parsing */
int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
{
int i, j;
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{
/* Is this channel an interleaved 256 + 256 block ? */
p_ac3dec->audblk.blksw[i] = GetBits (&p_ac3dec->bit_stream,1);
}
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{
/* Should we dither this channel? */
p_ac3dec->audblk.dithflag[i] = GetBits (&p_ac3dec->bit_stream,1);
}
/* Does dynamic range control exist? */
if ((p_ac3dec->audblk.dynrnge = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get dynamic range info */
p_ac3dec->audblk.dynrng = GetBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
/* If we're in dual mono mode then get the second channel DR info */
if (p_ac3dec->bsi.acmod == 0)
{
/* Does dynamic range control two exist? */
if ((p_ac3dec->audblk.dynrng2e = GetBits (&p_ac3dec->bit_stream,1)))
{
/* Get dynamic range info */
p_ac3dec->audblk.dynrng2 = GetBits (&p_ac3dec->bit_stream,8);
p_ac3dec->total_bits_read += 8;
}
p_ac3dec->total_bits_read += 1;
}
/* Does coupling strategy exist? */
p_ac3dec->audblk.cplstre = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 2 + 2 * p_ac3dec->bsi.nfchans;
if ((!blknum) && (!p_ac3dec->audblk.cplstre))
{
return 1;
}
if (p_ac3dec->audblk.cplstre)
{
/* Is coupling turned on? */
if ((p_ac3dec->audblk.cplinu = GetBits (&p_ac3dec->bit_stream,1)))
{
int nb_coupled_channels;
nb_coupled_channels = 0;
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{
p_ac3dec->audblk.chincpl[i] = GetBits (&p_ac3dec->bit_stream,1);
if (p_ac3dec->audblk.chincpl[i])
{
nb_coupled_channels++;
}
}
p_ac3dec->total_bits_read += p_ac3dec->bsi.nfchans;
if (nb_coupled_channels < 2)
{
return 1;
}
if (p_ac3dec->bsi.acmod == 0x2)
{
p_ac3dec->audblk.phsflginu = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
}
p_ac3dec->audblk.cplbegf = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cplendf = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->total_bits_read += 8;
if (p_ac3dec->audblk.cplbegf > p_ac3dec->audblk.cplendf + 2)
{
return 1;
}
p_ac3dec->audblk.ncplsubnd = (p_ac3dec->audblk.cplendf + 2) - p_ac3dec->audblk.cplbegf + 1;
/* Calculate the start and end bins of the coupling channel */
p_ac3dec->audblk.cplstrtmant = (p_ac3dec->audblk.cplbegf * 12) + 37 ;
p_ac3dec->audblk.cplendmant = ((p_ac3dec->audblk.cplendf + 3) * 12) + 37;
/* The number of combined subbands is ncplsubnd minus each combined
* band */
p_ac3dec->audblk.ncplbnd = p_ac3dec->audblk.ncplsubnd;
for (i=1; i< p_ac3dec->audblk.ncplsubnd; i++)
{
p_ac3dec->audblk.cplbndstrc[i] = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->audblk.ncplbnd -= p_ac3dec->audblk.cplbndstrc[i];
}
p_ac3dec->total_bits_read += p_ac3dec->audblk.ncplsubnd - 1;
}
p_ac3dec->total_bits_read += 1;
}
if (p_ac3dec->audblk.cplinu)
{
/* Loop through all the channels and get their coupling co-ords */
for (i=0; i < p_ac3dec->bsi.nfchans;i++)
{
if (!p_ac3dec->audblk.chincpl[i])
{
continue;
}
/* Is there new coupling co-ordinate info? */
p_ac3dec->audblk.cplcoe[i] = GetBits (&p_ac3dec->bit_stream,1);
if ((!blknum) && (!p_ac3dec->audblk.cplcoe[i]))
{
return 1;
}
if (p_ac3dec->audblk.cplcoe[i])
{
p_ac3dec->audblk.mstrcplco[i] = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
for (j=0;j < p_ac3dec->audblk.ncplbnd; j++)
{
p_ac3dec->audblk.cplcoexp[i][j] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cplcomant[i][j] = GetBits (&p_ac3dec->bit_stream,4);
}
p_ac3dec->total_bits_read += 8 * p_ac3dec->audblk.ncplbnd;
}
}
p_ac3dec->total_bits_read += p_ac3dec->bsi.nfchans;
/* If we're in dual mono mode, there's going to be some phase info */
if ((p_ac3dec->bsi.acmod == 0x2) && p_ac3dec->audblk.phsflginu &&
(p_ac3dec->audblk.cplcoe[0] || p_ac3dec->audblk.cplcoe[1]))
{
for (j=0; j < p_ac3dec->audblk.ncplbnd; j++)
{
p_ac3dec->audblk.phsflg[j] = GetBits (&p_ac3dec->bit_stream,1);
}
p_ac3dec->total_bits_read += p_ac3dec->audblk.ncplbnd;
}
}
/* If we're in dual mono mode, there may be a rematrix strategy */
if (p_ac3dec->bsi.acmod == 0x2)
{
p_ac3dec->audblk.rematstr = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (!p_ac3dec->audblk.rematstr))
{
return 1;
}
if (p_ac3dec->audblk.rematstr)
{
if (p_ac3dec->audblk.cplinu == 0)
{
for (i = 0; i < 4; i++)
{
p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
}
p_ac3dec->total_bits_read += 4;
}
if ((p_ac3dec->audblk.cplbegf > 2) && p_ac3dec->audblk.cplinu)
{
for (i = 0; i < 4; i++)
{
p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
}
p_ac3dec->total_bits_read += 4;
}
if ((p_ac3dec->audblk.cplbegf <= 2) && p_ac3dec->audblk.cplinu)
{
for (i = 0; i < 3; i++)
{
p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
}
p_ac3dec->total_bits_read += 3;
}
if ((p_ac3dec->audblk.cplbegf == 0) && p_ac3dec->audblk.cplinu)
{
for (i = 0; i < 2; i++)
{
p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
}
p_ac3dec->total_bits_read += 2;
}
}
}
if (p_ac3dec->audblk.cplinu)
{
/* Get the coupling channel exponent strategy */
p_ac3dec->audblk.cplexpstr = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
if ((!blknum) && (p_ac3dec->audblk.cplexpstr == EXP_REUSE))
{
return 1;
}
if (p_ac3dec->audblk.cplexpstr==0)
{
p_ac3dec->audblk.ncplgrps = 0;
}
else
{
p_ac3dec->audblk.ncplgrps = (p_ac3dec->audblk.cplendmant - p_ac3dec->audblk.cplstrtmant) /
(3 << (p_ac3dec->audblk.cplexpstr-1));
}
}
for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
{
p_ac3dec->audblk.chexpstr[i] = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
if ((!blknum) && (p_ac3dec->audblk.chexpstr[i] == EXP_REUSE))
{
return 1;
}
}
/* Get the exponent strategy for lfe channel */
if (p_ac3dec->bsi.lfeon)
{
p_ac3dec->audblk.lfeexpstr = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (p_ac3dec->audblk.lfeexpstr == EXP_REUSE))
{
return 1;
}
}
/* Determine the bandwidths of all the fbw channels */
for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
{
u16 grp_size;
if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE)
{
if (p_ac3dec->audblk.cplinu && p_ac3dec->audblk.chincpl[i])
{
p_ac3dec->audblk.endmant[i] = p_ac3dec->audblk.cplstrtmant;
}
else
{
p_ac3dec->audblk.chbwcod[i] = GetBits (&p_ac3dec->bit_stream,6);
p_ac3dec->total_bits_read += 6;
if (p_ac3dec->audblk.chbwcod[i] > 60)
{
return 1;
}
p_ac3dec->audblk.endmant[i] = ((p_ac3dec->audblk.chbwcod[i] + 12) * 3) + 37;
}
/* Calculate the number of exponent groups to fetch */
grp_size = 3 * (1 << (p_ac3dec->audblk.chexpstr[i] - 1));
p_ac3dec->audblk.nchgrps[i] = (p_ac3dec->audblk.endmant[i] - 1 + (grp_size - 3)) / grp_size;
}
}
/* Get the coupling exponents if they exist */
if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cplexpstr != EXP_REUSE))
{
p_ac3dec->audblk.cplabsexp = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->total_bits_read += 4;
for (i=0; i< p_ac3dec->audblk.ncplgrps;i++)
{
p_ac3dec->audblk.cplexps[i] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 7;
if (p_ac3dec->audblk.cplexps[i] >= 125)
{
return 1;
}
}
}
/* Get the fwb channel exponents */
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{
if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE)
{
p_ac3dec->audblk.exps[i][0] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->total_bits_read += 4;
for (j=1; j<=p_ac3dec->audblk.nchgrps[i];j++)
{
p_ac3dec->audblk.exps[i][j] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 7;
if (p_ac3dec->audblk.exps[i][j] >= 125)
{
return 1;
}
}
p_ac3dec->audblk.gainrng[i] = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
}
}
/* Get the lfe channel exponents */
if (p_ac3dec->bsi.lfeon && (p_ac3dec->audblk.lfeexpstr != EXP_REUSE))
{
p_ac3dec->audblk.lfeexps[0] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.lfeexps[1] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 11;
if (p_ac3dec->audblk.lfeexps[1] >= 125)
{
return 1;
}
p_ac3dec->audblk.lfeexps[2] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 7;
if (p_ac3dec->audblk.lfeexps[2] >= 125)
{
return 1;
}
}
/* Get the parametric bit allocation parameters */
p_ac3dec->audblk.baie = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (!p_ac3dec->audblk.baie))
{
return 1;
}
if (p_ac3dec->audblk.baie)
{
p_ac3dec->audblk.sdcycod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.fdcycod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.sgaincod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.dbpbcod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.floorcod = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->total_bits_read += 11;
}
/* Get the SNR off set info if it exists */
p_ac3dec->audblk.snroffste = GetBits (&p_ac3dec->bit_stream,1);
if ((!blknum) && (!p_ac3dec->audblk.snroffste))
{
return 1;
}
if (p_ac3dec->audblk.snroffste)
{
p_ac3dec->audblk.csnroffst = GetBits (&p_ac3dec->bit_stream,6);
p_ac3dec->total_bits_read += 6;
if (p_ac3dec->audblk.cplinu)
{
p_ac3dec->audblk.cplfsnroffst = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cplfgaincod = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->total_bits_read += 7;
}
for (i = 0;i < p_ac3dec->bsi.nfchans; i++)
{
p_ac3dec->audblk.fsnroffst[i] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.fgaincod[i] = GetBits (&p_ac3dec->bit_stream,3);
}
p_ac3dec->total_bits_read += 7 * p_ac3dec->bsi.nfchans;
if (p_ac3dec->bsi.lfeon)
{
p_ac3dec->audblk.lfefsnroffst = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.lfefgaincod = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->total_bits_read += 7;
}
}
/* Get coupling leakage info if it exists */
if (p_ac3dec->audblk.cplinu)
{
p_ac3dec->audblk.cplleake = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (!p_ac3dec->audblk.cplleake))
{
return 1;
}
if (p_ac3dec->audblk.cplleake)
{
p_ac3dec->audblk.cplfleak = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->audblk.cplsleak = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->total_bits_read += 6;
}
}
/* Get the delta bit alloaction info */
p_ac3dec->audblk.deltbaie = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if (p_ac3dec->audblk.deltbaie)
{
if (p_ac3dec->audblk.cplinu)
{
p_ac3dec->audblk.cpldeltbae = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
if (p_ac3dec->audblk.cpldeltbae == 3)
{
return 1;
}
}
for (i = 0;i < p_ac3dec->bsi.nfchans; i++)
{
p_ac3dec->audblk.deltbae[i] = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
if (p_ac3dec->audblk.deltbae[i] == 3)
{
return 1;
}
}
if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cpldeltbae == DELTA_BIT_NEW))
{
p_ac3dec->audblk.cpldeltnseg = GetBits (&p_ac3dec->bit_stream,3);
for (i = 0;i < p_ac3dec->audblk.cpldeltnseg + 1; i++)
{
p_ac3dec->audblk.cpldeltoffst[i] = GetBits (&p_ac3dec->bit_stream,5);
p_ac3dec->audblk.cpldeltlen[i] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cpldeltba[i] = GetBits (&p_ac3dec->bit_stream,3);
}
p_ac3dec->total_bits_read += 12 * (p_ac3dec->audblk.cpldeltnseg + 1) + 3;
}
for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
{
if (p_ac3dec->audblk.deltbae[i] == DELTA_BIT_NEW)
{
p_ac3dec->audblk.deltnseg[i] = GetBits (&p_ac3dec->bit_stream,3);
// if (p_ac3dec->audblk.deltnseg[i] >= 8)
// fprintf (stderr, "parse debug: p_ac3dec->audblk.deltnseg[%i] == %i\n", i, p_ac3dec->audblk.deltnseg[i]);
for (j = 0; j < p_ac3dec->audblk.deltnseg[i] + 1; j++)
{
p_ac3dec->audblk.deltoffst[i][j] = GetBits (&p_ac3dec->bit_stream,5);
p_ac3dec->audblk.deltlen[i][j] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.deltba[i][j] = GetBits (&p_ac3dec->bit_stream,3);
}
p_ac3dec->total_bits_read += 12 * (p_ac3dec->audblk.deltnseg[i] + 1) + 3;
}
}
}
/* Check to see if there's any dummy info to get */
p_ac3dec->audblk.skiple = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if (p_ac3dec->audblk.skiple)
{
p_ac3dec->audblk.skipl = GetBits (&p_ac3dec->bit_stream,9);
for (i = 0; i < p_ac3dec->audblk.skipl ; i++)
{
GetBits (&p_ac3dec->bit_stream,8);
}
p_ac3dec->total_bits_read += 8 * p_ac3dec->audblk.skipl + 9;
}
parse_audblk_stats(p_ac3dec);
return 0;
}
void parse_auxdata (ac3dec_t * p_ac3dec)
{
int i;
int skip_length;
skip_length = (p_ac3dec->syncinfo.frame_size * 16) - p_ac3dec->total_bits_read - 17 - 1;
for (i = 0; i < skip_length; i++)
{
RemoveBits (&p_ac3dec->bit_stream,1);
}
/* get the auxdata exists bit */
RemoveBits (&p_ac3dec->bit_stream,1);
/* Skip the CRC reserved bit */
RemoveBits (&p_ac3dec->bit_stream,1);
/* Get the crc */
RemoveBits (&p_ac3dec->bit_stream,16);
}
static void parse_bsi_stats (ac3dec_t * p_ac3dec) /* Some stats */
{
#if 0
struct mixlev_s
{
float clev;
char *desc;
};
static const char *service_ids[8] =
{
"CM","ME","VI","HI",
"D", "C","E", "VO"
};
/*
static const struct mixlev_s cmixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"},
{0.500, "(-6.0 dB)"}, {1.0, "Invalid"}
};
static const struct mixlev_s smixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"},
{ 0.0, "off "}, { 1.0, "Invalid"}
};
*/
static int i=0;
if ( !i )
{
/* if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
if (p_ac3dec->bsi.acmod & 0x4)
printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
*/
intf_Msg ( "(ac3dec_parsebsi) %s %d.%d Mode",
service_ids[p_ac3dec->bsi.bsmod],
p_ac3dec->bsi.nfchans,p_ac3dec->bsi.lfeon);
}
i++;
if ( i > 100 )
i = 0;
#endif
}
static void parse_audblk_stats (ac3dec_t * p_ac3dec)
{
#if 0
char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "};
u32 i;
intf_ErrMsg ("(ac3dec_parseaudblk) ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.cplinu ? "cpl on" : "cpl off");
intf_ErrMsg ("%s ",p_ac3dec->audblk.baie? "bai" : " ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.snroffste? "snroffst" : " ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.deltbaie? "deltba" : " ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.phsflginu? "phsflg" : " ");
intf_ErrMsg ("(%s %s %s %s %s) ",exp_strat_tbl[p_ac3dec->audblk.chexpstr[0]],
exp_strat_tbl[p_ac3dec->audblk.chexpstr[1]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[2]],
exp_strat_tbl[p_ac3dec->audblk.chexpstr[3]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[4]]);
intf_ErrMsg ("[");
for(i=0;i<p_ac3dec->bsi.nfchans;i++)
intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]);
intf_ErrMsg ("]");
#endif
}

View File

@ -1,79 +0,0 @@
/*****************************************************************************
* ac3_rematrix.c: ac3 audio rematrixing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_rematrix.c,v 1.8 2002/06/01 12:31:58 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_adec.h"
struct rematrix_band_s {
u32 start;
u32 end;
};
static const struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}};
static inline u32 min_value (u32 a, u32 b)
{
return (a < b ? a : b);
}
/* This routine simply does stereo rematixing for the 2 channel
* stereo mode */
void rematrix (ac3dec_t * p_ac3dec)
{
u32 num_bands;
u32 start;
u32 end;
u32 i,j;
float left,right;
if (p_ac3dec->audblk.cplinu || p_ac3dec->audblk.cplbegf > 2)
num_bands = 4;
else if (p_ac3dec->audblk.cplbegf > 0)
num_bands = 3;
else
num_bands = 2;
for (i=0;i < num_bands; i++) {
if (!p_ac3dec->audblk.rematflg[i])
continue;
start = rematrix_band[i].start;
end = min_value(rematrix_band[i].end ,12 * p_ac3dec->audblk.cplbegf + 36);
for (j=start;j < end; j++) {
left = 0.5f * ( *(p_ac3dec->samples+j) + *(p_ac3dec->samples+256+j) );
right = 0.5f * ( *(p_ac3dec->samples+j) - *(p_ac3dec->samples+256+j) );
*(p_ac3dec->samples+j) = left;
*(p_ac3dec->samples+256+j) = right;
}
}
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1 +0,0 @@
ac3_spdif_SOURCES = ac3_spdif.c

View File

@ -1,431 +0,0 @@
/*****************************************************************************
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ac3_spdif.c,v 1.32 2002/07/31 20:56:50 sam Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
* German Gomez Garcia <german@piraos.com>
*
* 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
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* memcpy() */
#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include <vlc/aout.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "ac3_spdif.h"
/****************************************************************************
* Local prototypes
****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( ac3_spdif_thread_t * );
static void EndThread ( ac3_spdif_thread_t * );
static void BitstreamCallback ( bit_stream_t *, vlc_bool_t );
int ac3_parse_syncinfo ( struct ac3_spdif_thread_s * );
/****************************************************************************
* Local structures and tables
****************************************************************************/
static const frame_size_t p_frame_size_code[64] =
{
{ 32 ,{64 ,69 ,96 } },
{ 32 ,{64 ,70 ,96 } },
{ 40 ,{80 ,87 ,120 } },
{ 40 ,{80 ,88 ,120 } },
{ 48 ,{96 ,104 ,144 } },
{ 48 ,{96 ,105 ,144 } },
{ 56 ,{112 ,121 ,168 } },
{ 56 ,{112 ,122 ,168 } },
{ 64 ,{128 ,139 ,192 } },
{ 64 ,{128 ,140 ,192 } },
{ 80 ,{160 ,174 ,240 } },
{ 80 ,{160 ,175 ,240 } },
{ 96 ,{192 ,208 ,288 } },
{ 96 ,{192 ,209 ,288 } },
{ 112 ,{224 ,243 ,336 } },
{ 112 ,{224 ,244 ,336 } },
{ 128 ,{256 ,278 ,384 } },
{ 128 ,{256 ,279 ,384 } },
{ 160 ,{320 ,348 ,480 } },
{ 160 ,{320 ,349 ,480 } },
{ 192 ,{384 ,417 ,576 } },
{ 192 ,{384 ,418 ,576 } },
{ 224 ,{448 ,487 ,672 } },
{ 224 ,{448 ,488 ,672 } },
{ 256 ,{512 ,557 ,768 } },
{ 256 ,{512 ,558 ,768 } },
{ 320 ,{640 ,696 ,960 } },
{ 320 ,{640 ,697 ,960 } },
{ 384 ,{768 ,835 ,1152 } },
{ 384 ,{768 ,836 ,1152 } },
{ 448 ,{896 ,975 ,1344 } },
{ 448 ,{896 ,976 ,1344 } },
{ 512 ,{1024 ,1114 ,1536 } },
{ 512 ,{1024 ,1115 ,1536 } },
{ 576 ,{1152 ,1253 ,1728 } },
{ 576 ,{1152 ,1254 ,1728 } },
{ 640 ,{1280 ,1393 ,1920 } },
{ 640 ,{1280 ,1394 ,1920 } }
};
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("SPDIF pass-through AC3 decoder") );
set_capability( "decoder", 0 );
set_callbacks( OpenDecoder, NULL );
add_shortcut( "pass_through" );
add_shortcut( "pass" );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
/****************************************************************************
* RunDecoder: the whole thing
****************************************************************************
* This function is called just after the thread is launched.
****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo )
{
ac3_spdif_thread_t * p_spdif;
mtime_t i_frame_time;
vlc_bool_t b_sync;
/* PTS of the current frame */
mtime_t i_current_pts = 0;
u16 i_length;
/* Allocate the memory needed to store the thread's structure */
p_spdif = malloc( sizeof(ac3_spdif_thread_t) );
if( p_spdif == NULL )
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
}
p_spdif->p_fifo = p_fifo;
if (InitThread( p_spdif ) )
{
if( p_fifo->b_error )
{
msg_Err( p_fifo, "could not initialize thread" );
}
DecoderError( p_fifo );
free( p_spdif );
return( -1 );
}
/* Compute the theorical duration of an ac3 frame */
i_frame_time = 1000000 * AC3_FRAME_SIZE /
p_spdif->ac3_info.i_sample_rate;
i_length = p_spdif->ac3_info.i_frame_size;
while( !p_spdif->p_fifo->b_die && !p_spdif->p_fifo->b_error )
{
p_spdif->p_ac3[0] = 0x0b;
p_spdif->p_ac3[1] = 0x77;
/* Handle the dates */
if( p_spdif->i_real_pts )
{
mtime_t i_delta = p_spdif->i_real_pts - i_current_pts -
i_frame_time;
if( i_delta > i_frame_time || i_delta < -i_frame_time )
{
msg_Warn( p_fifo,
"date discontinuity (%d)", i_delta );
}
i_current_pts = p_spdif->i_real_pts;
p_spdif->i_real_pts = 0;
}
else
{
i_current_pts += i_frame_time;
}
// wait a little to avoid an input flood from the a52 input
mwait( i_current_pts - 500000 );
vlc_mutex_lock (&p_spdif->p_aout_fifo->data_lock);
p_spdif->p_aout_fifo->date[p_spdif->p_aout_fifo->i_end_frame] =
i_current_pts;
p_spdif->p_aout_fifo->i_end_frame =
(p_spdif->p_aout_fifo->i_end_frame + 1 ) & AOUT_FIFO_SIZE;
p_spdif->p_ac3 = ((u8*)(p_spdif->p_aout_fifo->buffer)) +
(p_spdif->p_aout_fifo->i_end_frame * i_length );
vlc_mutex_unlock (&p_spdif->p_aout_fifo->data_lock);
/* Find syncword again in case of stream discontinuity */
/* Here we have p_spdif->i_pts == 0
* Therefore a non-zero value after a call to GetBits() means the PES
* has changed. */
b_sync = 0;
while( !p_spdif->p_fifo->b_die
&& !p_spdif->p_fifo->b_error
&& !b_sync )
{
while( !p_spdif->p_fifo->b_die
&& !p_spdif->p_fifo->b_error
&& GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
p_spdif->i_real_pts = p_spdif->i_pts;
p_spdif->i_pts = 0;
b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
}
RemoveBits( &p_spdif->bit_stream, 8 );
/* Read data from bitstream */
GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + 2, i_length - 2 );
}
/* If b_error is set, the ac3 spdif thread enters the error loop */
if( p_spdif->p_fifo->b_error )
{
DecoderError( p_spdif->p_fifo );
}
/* End of the ac3 decoder thread */
EndThread( p_spdif );
return( 0 );
}
/****************************************************************************
* InitThread: initialize thread data and create output fifo
****************************************************************************/
static int InitThread( ac3_spdif_thread_t * p_spdif )
{
vlc_bool_t b_sync = 0;
/* Temporary buffer to store first ac3 frame */
p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
if( p_spdif->p_ac3 == NULL )
{
free( p_spdif->p_ac3 );
return( -1 );
}
/*
* Initialize the thread properties
*/
p_spdif->p_fifo = p_spdif->p_fifo;
InitBitstream( &p_spdif->bit_stream, p_spdif->p_fifo,
BitstreamCallback, (void*)p_spdif );
/* Find syncword */
while( !p_spdif->p_fifo->b_die
&& !p_spdif->p_fifo->b_error
&& !b_sync )
{
while( !p_spdif->p_fifo->b_die
&& !p_spdif->p_fifo->b_error
&& GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
p_spdif->i_real_pts = p_spdif->i_pts;
p_spdif->i_pts = 0;
b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
}
if( p_spdif->p_fifo->b_die || p_spdif->p_fifo->b_error )
{
return -1;
}
RemoveBits( &p_spdif->bit_stream, 8 );
/* Check stream properties */
if( ac3_parse_syncinfo( p_spdif ) < 0 )
{
msg_Err( p_spdif->p_fifo, "stream not valid" );
return( -1 );
}
/* Check that we can handle the rate
* FIXME: we should check that we have the same rate for all fifos
* but all rates should be supported by the decoder (32, 44.1, 48) */
if( p_spdif->ac3_info.i_sample_rate != 48000 )
{
msg_Err( p_spdif->p_fifo,
"only 48000 Hz streams tested, expect weird things!" );
}
/* The audio output need to be ready for an ac3 stream */
p_spdif->i_previous_format = config_GetInt( p_spdif->p_fifo,
"audio-format" );
config_PutInt( p_spdif->p_fifo, "audio-format", 8 );
/* Creating the audio output fifo */
p_spdif->p_aout_fifo =
aout_CreateFifo( p_spdif->p_fifo, AOUT_FIFO_SPDIF,
1, p_spdif->ac3_info.i_sample_rate,
p_spdif->ac3_info.i_frame_size, NULL );
if( p_spdif->p_aout_fifo == NULL )
{
return( -1 );
}
msg_Dbg( p_spdif->p_fifo, "aout fifo #%d created",
p_spdif->p_aout_fifo->i_fifo );
/* Put read data into fifo */
memcpy( (u8*)(p_spdif->p_aout_fifo->buffer) +
(p_spdif->p_aout_fifo->i_end_frame *
p_spdif->ac3_info.i_frame_size ),
p_spdif->p_ac3, sizeof(sync_frame_t) );
free( p_spdif->p_ac3 );
p_spdif->p_ac3 = ((u8*)(p_spdif->p_aout_fifo->buffer) +
(p_spdif->p_aout_fifo->i_end_frame *
p_spdif->ac3_info.i_frame_size ));
GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
return( 0 );
}
/*****************************************************************************
* EndThread : ac3 spdif thread destruction
*****************************************************************************/
static void EndThread( ac3_spdif_thread_t * p_spdif )
{
/* If the audio output fifo was created, we destroy it */
if( p_spdif->p_aout_fifo != NULL )
{
aout_DestroyFifo( p_spdif->p_aout_fifo );
/* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock( &(p_spdif->p_aout_fifo->data_lock ) );
vlc_cond_signal( &(p_spdif->p_aout_fifo->data_wait ) );
vlc_mutex_unlock( &(p_spdif->p_aout_fifo->data_lock ) );
}
/* restore previous setting for output format */
config_PutInt( p_spdif->p_fifo, "audio-format",
p_spdif->i_previous_format );
/* Destroy descriptor */
free( p_spdif );
}
/*****************************************************************************
* BitstreamCallback: Import parameters from the new data/PES packet
*****************************************************************************
* This function is called by input's NextDataPacket.
*****************************************************************************/
static void BitstreamCallback( bit_stream_t * p_bit_stream,
vlc_bool_t b_new_pes )
{
ac3_spdif_thread_t * p_spdif;
if( b_new_pes )
{
p_spdif = (ac3_spdif_thread_t *)p_bit_stream->p_callback_arg;
/* p_bit_stream->p_byte += 3; */
p_spdif->i_pts =
p_bit_stream->p_decoder_fifo->p_first->i_pts;
p_bit_stream->p_decoder_fifo->p_first->i_pts = 0;
}
}
/****************************************************************************
* ac3_parse_syncinfo: parse ac3 sync info
****************************************************************************/
int ac3_parse_syncinfo( ac3_spdif_thread_t *p_spdif )
{
int p_sample_rates[4] = { 48000, 44100, 32000, -1 };
int i_frame_rate_code;
int i_frame_size_code;
sync_frame_t * p_sync_frame;
/* Read sync frame */
GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + 2,
sizeof(sync_frame_t) - 2 );
if( p_spdif->p_fifo->b_die ) return -1;
p_sync_frame = (sync_frame_t*)p_spdif->p_ac3;
/* Compute frame rate */
i_frame_rate_code = (p_sync_frame->syncinfo.code >> 6) & 0x03;
p_spdif->ac3_info.i_sample_rate = p_sample_rates[i_frame_rate_code];
if( p_spdif->ac3_info.i_sample_rate == -1 )
{
return -1;
}
/* Compute frame size */
i_frame_size_code = p_sync_frame->syncinfo.code & 0x3f;
p_spdif->ac3_info.i_frame_size = 2 *
p_frame_size_code[i_frame_size_code].i_frame_size[i_frame_rate_code];
p_spdif->ac3_info.i_bit_rate =
p_frame_size_code[i_frame_size_code].i_bit_rate;
if( ( ( p_sync_frame->bsi.bsidmod >> 3 ) & 0x1f ) != 0x08 )
{
return -1;
}
p_spdif->ac3_info.i_bs_mod = p_sync_frame->bsi.bsidmod & 0x7;
return 0;
}

View File

@ -1,93 +0,0 @@
/*****************************************************************************
* ac3_spdif.h: header for ac3 pass-through
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ac3_spdif.h,v 1.4 2002/06/01 12:31:58 sam Exp $
*
* Authors: Stéphane Borel <stef@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.
****************************************************************************/
/****************************************************************************
* information about ac3 frame
****************************************************************************/
typedef struct sync_frame_s
{
struct syncinfo
{
u8 syncword[2];
u8 crc1[2];
u8 code;
} syncinfo;
struct bsi
{
u8 bsidmod;
u8 acmod;
} bsi;
} sync_frame_t;
typedef struct frame_size_s
{
u16 i_bit_rate;
u16 i_frame_size[3];
} frame_size_t;
typedef struct ac3_info_s
{
int i_bit_rate;
int i_frame_size;
int i_sample_rate;
int i_bs_mod;
} ac3_info_t;
/*****************************************************************************
* ac3_spdif_thread_t : ac3 pass-through thread descriptor
*****************************************************************************/
typedef struct ac3_spdif_thread_s
{
/*
* Thread properties
*/
vlc_thread_t thread_id; /* id for thread functions */
/*
* Input properties
*/
decoder_fifo_t * p_fifo; /* stores the PES stream data */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
int i_available;
/*
* Decoder properties
*/
ac3_info_t ac3_info;
u8 * p_ac3;
/* current pes date */
mtime_t i_pts;
mtime_t i_real_pts;
/*
* Output properties
*/
int i_previous_format;
aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */
} ac3_spdif_thread_t;

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,3 +0,0 @@
file_SOURCES = file.c
udp_SOURCES = udp.c
http_SOURCES = http.c

View File

@ -1,151 +0,0 @@
/*****************************************************************************
* file.c: file input (file: access plug-in)
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: file.c,v 1.8 2002/07/31 20:56:50 sam Exp $
*
* Authors: Christophe Massiot <massiot@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
*****************************************************************************/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( _MSC_VER ) && defined( _WIN32 )
# include <io.h>
#endif
/*****************************************************************************
* Open: open the file
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
char * psz_name = p_input->psz_name;
int i_stat;
struct stat stat_info;
input_socket_t * p_access_data;
vlc_bool_t b_stdin;
p_input->i_mtu = 0;
b_stdin = psz_name[0] == '-' && psz_name[1] == '\0';
if( !b_stdin && (i_stat = stat( psz_name, &stat_info )) == (-1) )
{
msg_Err( p_input, "cannot stat() file `%s' (%s)",
psz_name, strerror(errno));
return( -1 );
}
p_input->pf_read = input_FDRead;
p_input->pf_set_program = input_SetProgram;
p_input->pf_set_area = NULL;
p_input->pf_seek = input_FDSeek;
vlc_mutex_lock( &p_input->stream.stream_lock );
if( *p_input->psz_access && !strncmp( p_input->psz_access, "stream", 7 ) )
{
/* stream:%s */
p_input->stream.b_pace_control = 0;
p_input->stream.b_seekable = 0;
p_input->stream.p_selected_area->i_size = 0;
}
else
{
/* file:%s or %s */
p_input->stream.b_pace_control = 1;
if( b_stdin )
{
p_input->stream.b_seekable = 0;
p_input->stream.p_selected_area->i_size = 0;
}
else if( S_ISREG(stat_info.st_mode) || S_ISCHR(stat_info.st_mode)
|| S_ISBLK(stat_info.st_mode) )
{
p_input->stream.b_seekable = 1;
p_input->stream.p_selected_area->i_size = stat_info.st_size;
}
else if( S_ISFIFO(stat_info.st_mode)
#if !defined( SYS_BEOS ) && !defined( WIN32 )
|| S_ISSOCK(stat_info.st_mode)
#endif
)
{
p_input->stream.b_seekable = 0;
p_input->stream.p_selected_area->i_size = 0;
}
else
{
vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Err( p_input, "unknown file type for `%s'", psz_name );
return( -1 );
}
}
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.i_method = INPUT_METHOD_FILE;
vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Dbg( p_input, "opening file `%s'", psz_name );
p_access_data = malloc( sizeof(input_socket_t) );
p_input->p_access_data = (void *)p_access_data;
if( p_access_data == NULL )
{
msg_Err( p_input, "out of memory" );
return( -1 );
}
if( b_stdin )
{
p_access_data->i_handle = 0;
}
else if( (p_access_data->i_handle = open( psz_name,
/*O_NONBLOCK | O_LARGEFILE*/ 0 )) == (-1) )
{
msg_Err( p_input, "cannot open file %s (%s)", psz_name,
strerror(errno) );
free( p_access_data );
return( -1 );
}
return( 0 );
}
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("Standard filesystem file reading") );
set_capability( "access", 50 );
add_shortcut( "stream" );
set_callbacks( Open, __input_FDClose );
vlc_module_end();

View File

@ -1,500 +0,0 @@
/*****************************************************************************
* http.c: HTTP access plug-in
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: http.c,v 1.19 2002/07/31 20:56:50 sam Exp $
*
* Authors: Christophe Massiot <massiot@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
*****************************************************************************/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( _MSC_VER ) && defined( _WIN32 )
# include <io.h>
#endif
#ifdef WIN32
# include <winsock2.h>
# include <ws2tcpip.h>
# ifndef IN_MULTICAST
# define IN_MULTICAST(a) IN_CLASSD(a)
# endif
#else
# include <sys/socket.h>
#endif
#include "network.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetProgram ( input_thread_t *, pgrm_descriptor_t * );
static void Seek ( input_thread_t *, off_t );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("HTTP access module") );
set_capability( "access", 0 );
add_shortcut( "http4" );
add_shortcut( "http6" );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* _input_socket_t: private access plug-in data, modified to add private
* fields
*****************************************************************************/
typedef struct _input_socket_s
{
input_socket_t _socket;
char * psz_network;
network_socket_t socket_desc;
char psz_buffer[256];
char * psz_name;
} _input_socket_t;
/*****************************************************************************
* HTTPConnect: connect to the server and seek to i_tell
*****************************************************************************/
static int HTTPConnect( input_thread_t * p_input, off_t i_tell )
{
_input_socket_t * p_access_data = p_input->p_access_data;
module_t * p_network;
char psz_buffer[256];
byte_t * psz_parser;
int i_returncode, i;
char * psz_return_alpha;
/* Find an appropriate network module */
p_input->p_private = (void*) &p_access_data->socket_desc;
p_network = module_Need( p_input, "network", p_access_data->psz_network );
if( p_network == NULL )
{
return( -1 );
}
module_Unneed( p_input, p_network );
p_access_data->_socket.i_handle = p_access_data->socket_desc.i_handle;
# define HTTP_USERAGENT "User-Agent: " COPYRIGHT_MESSAGE "\r\n"
# define HTTP_END "\r\n"
if ( p_input->stream.b_seekable )
{
snprintf( psz_buffer, sizeof(psz_buffer),
"%s"
"Range: bytes=%lld-\r\n"
HTTP_USERAGENT HTTP_END,
p_access_data->psz_buffer, i_tell );
}
else
{
snprintf( psz_buffer, sizeof(psz_buffer),
"%s"
HTTP_USERAGENT HTTP_END,
p_access_data->psz_buffer );
}
psz_buffer[sizeof(psz_buffer) - 1] = '\0';
/* Send GET ... */
if( send( p_access_data->_socket.i_handle, psz_buffer,
strlen( psz_buffer ), 0 ) == (-1) )
{
msg_Err( p_input, "cannot send request (%s)", strerror(errno) );
input_FDNetworkClose( p_input );
return( -1 );
}
/* Prepare the input thread for reading. */
p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
/* FIXME: we shouldn't have to do that ! It's UGLY but mandatory because
* input_FillBuffer assumes p_input->pf_read exists */
p_input->pf_read = input_FDNetworkRead;
while( !input_FillBuffer( p_input ) )
{
if( p_input->b_die || p_input->b_error )
{
input_FDNetworkClose( p_input );
return( -1 );
}
}
/* Parse HTTP header. */
#define MAX_LINE 1024
/* get the returncode */
if( input_Peek( p_input, &psz_parser, MAX_LINE ) <= 0 )
{
msg_Err( p_input, "not enough data" );
input_FDNetworkClose( p_input );
return( -1 );
}
if( !strncmp( psz_parser, "HTTP/1.",
strlen("HTTP/1.") ) )
{
psz_parser += strlen("HTTP 1.") + 2;
i_returncode = atoi( psz_parser );
msg_Dbg( p_input, "HTTP server replied: %i", i_returncode );
psz_parser += 4;
for ( i = 0; psz_parser[i] != '\r' || psz_parser[i+1] != '\n'; i++ )
{
;
}
psz_return_alpha = malloc( i + 1 );
memcpy( psz_return_alpha, psz_parser, i );
psz_return_alpha[i] = '\0';
}
else
{
msg_Err( p_input, "invalid http reply" );
return -1;
}
if ( i_returncode >= 400 ) /* something is wrong */
{
msg_Err( p_input, "%i %s", i_returncode,
psz_return_alpha );
return -1;
}
for( ; ; )
{
if( input_Peek( p_input, &psz_parser, MAX_LINE ) <= 0 )
{
msg_Err( p_input, "not enough data" );
input_FDNetworkClose( p_input );
return( -1 );
}
if( psz_parser[0] == '\r' && psz_parser[1] == '\n' )
{
/* End of header. */
p_input->p_current_data += 2;
break;
}
if( !strncmp( psz_parser, "Content-Length: ",
strlen("Content-Length: ") ) )
{
psz_parser += strlen("Content-Length: ");
vlc_mutex_lock( &p_input->stream.stream_lock );
#ifdef HAVE_ATOLL
p_input->stream.p_selected_area->i_size = atoll( psz_parser )
+ i_tell;
#else
/* FIXME : this won't work for 64-bit lengths */
p_input->stream.p_selected_area->i_size = atoi( psz_parser )
+ i_tell;
#endif
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
while( *psz_parser != '\r' && psz_parser < p_input->p_last_data )
{
psz_parser++;
}
p_input->p_current_data = psz_parser + 2;
}
if( p_input->stream.p_selected_area->i_size )
{
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell = i_tell
+ (p_input->p_last_data - p_input->p_current_data);
p_input->stream.b_seekable = 1;
p_input->stream.b_changed = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
return( 0 );
}
/*****************************************************************************
* Open: parse URL and open the remote file at the beginning
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
_input_socket_t * p_access_data;
char * psz_name = strdup(p_input->psz_name);
char * psz_parser = psz_name;
char * psz_server_addr = "";
char * psz_server_port = "";
char * psz_path = "";
char * psz_proxy;
int i_server_port = 0;
p_access_data = p_input->p_access_data = malloc( sizeof(_input_socket_t) );
if( p_access_data == NULL )
{
msg_Err( p_input, "out of memory" );
free(psz_name);
return( -1 );
}
p_access_data->psz_name = psz_name;
p_access_data->psz_network = "";
if( config_GetInt( p_input, "ipv4" ) )
{
p_access_data->psz_network = "ipv4";
}
if( config_GetInt( p_input, "ipv6" ) )
{
p_access_data->psz_network = "ipv6";
}
if( *p_input->psz_access )
{
/* Find out which shortcut was used */
if( !strncmp( p_input->psz_access, "http6", 6 ) )
{
p_access_data->psz_network = "ipv6";
}
else if( !strncmp( p_input->psz_access, "http4", 6 ) )
{
p_access_data->psz_network = "ipv4";
}
}
/* Parse psz_name syntax :
* //<hostname>[:<port>][/<path>] */
while( *psz_parser == '/' )
{
psz_parser++;
}
psz_server_addr = psz_parser;
while( *psz_parser && *psz_parser != ':' && *psz_parser != '/' )
{
psz_parser++;
}
if ( *psz_parser == ':' )
{
*psz_parser = '\0';
psz_parser++;
psz_server_port = psz_parser;
while( *psz_parser && *psz_parser != '/' )
{
psz_parser++;
}
}
if( *psz_parser == '/' )
{
*psz_parser = '\0';
psz_parser++;
psz_path = psz_parser;
}
/* Convert port format */
if( *psz_server_port )
{
i_server_port = strtol( psz_server_port, &psz_parser, 10 );
if( *psz_parser )
{
msg_Err( p_input, "cannot parse server port near %s", psz_parser );
free( p_input->p_access_data );
free( psz_name );
return( -1 );
}
}
if( i_server_port == 0 )
{
i_server_port = 80;
}
if( !*psz_server_addr )
{
msg_Err( p_input, "no server given" );
free( p_input->p_access_data );
free( psz_name );
return( -1 );
}
/* Check proxy */
if( (psz_proxy = getenv( "http_proxy" )) != NULL && *psz_proxy )
{
/* http://myproxy.mydomain:myport/ */
int i_proxy_port = 0;
/* Skip the protocol name */
while( *psz_proxy && *psz_proxy != ':' )
{
psz_proxy++;
}
/* Skip the "://" part */
while( *psz_proxy && (*psz_proxy == ':' || *psz_proxy == '/') )
{
psz_proxy++;
}
/* Found a proxy name */
if( *psz_proxy )
{
char *psz_port = psz_proxy;
/* Skip the hostname part */
while( *psz_port && *psz_port != ':' && *psz_port != '/' )
{
psz_port++;
}
/* Found a port name */
if( *psz_port )
{
char * psz_junk;
/* Replace ':' with '\0' */
*psz_port = '\0';
psz_port++;
psz_junk = psz_port;
while( *psz_junk && *psz_junk != '/' )
{
psz_junk++;
}
if( *psz_junk )
{
*psz_junk = '\0';
}
if( *psz_port != '\0' )
{
i_proxy_port = atoi( psz_port );
}
}
}
else
{
msg_Err( p_input, "http_proxy environment variable is invalid!" );
free( p_input->p_access_data );
free( psz_name );
return( -1 );
}
p_access_data->socket_desc.i_type = NETWORK_TCP;
p_access_data->socket_desc.psz_server_addr = psz_proxy;
p_access_data->socket_desc.i_server_port = i_proxy_port;
snprintf( p_access_data->psz_buffer, sizeof(p_access_data->psz_buffer),
"GET http://%s:%d/%s\r\n HTTP/1.0\r\n",
psz_server_addr, i_server_port, psz_path );
}
else
{
/* No proxy, direct connection. */
p_access_data->socket_desc.i_type = NETWORK_TCP;
p_access_data->socket_desc.psz_server_addr = psz_server_addr;
p_access_data->socket_desc.i_server_port = i_server_port;
snprintf( p_access_data->psz_buffer, sizeof(p_access_data->psz_buffer),
"GET /%s HTTP/1.1\r\nHost: %s\r\n",
psz_path, psz_server_addr );
}
p_access_data->psz_buffer[sizeof(p_access_data->psz_buffer) - 1] = '\0';
msg_Dbg( p_input, "opening server=%s port=%d path=%s",
psz_server_addr, i_server_port, psz_path );
p_input->pf_read = input_FDNetworkRead;
p_input->pf_set_program = SetProgram;
p_input->pf_set_area = NULL;
p_input->pf_seek = Seek;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_pace_control = 1;
p_input->stream.b_seekable = 1;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.p_selected_area->i_size = 0;
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_input->i_mtu = 0;
if( HTTPConnect( p_input, 0 ) )
{
char * psz_pos = strstr(p_access_data->psz_buffer, "HTTP/1.1");
p_input->stream.b_seekable = 0;
psz_pos[7] = '0';
if( HTTPConnect( p_input, 0 ) )
{
free( p_input->p_access_data );
free( psz_name );
return( -1 );
}
}
return 0;
}
/*****************************************************************************
* Close: free unused data structures
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
_input_socket_t * p_access_data =
(_input_socket_t *)p_input->p_access_data;
free( p_access_data->psz_name );
input_FDNetworkClose( p_input );
}
/*****************************************************************************
* SetProgram: do nothing
*****************************************************************************/
static int SetProgram( input_thread_t * p_input,
pgrm_descriptor_t * p_program )
{
return( 0 );
}
/*****************************************************************************
* Seek: close and re-open a connection at the right place
*****************************************************************************/
static void Seek( input_thread_t * p_input, off_t i_pos )
{
_input_socket_t * p_access_data = p_input->p_access_data;
close( p_access_data->_socket.i_handle );
msg_Dbg( p_input, "seeking to position %lld", i_pos );
HTTPConnect( p_input, i_pos );
}

View File

@ -1,251 +0,0 @@
/*****************************************************************************
* udp.c: raw UDP access plug-in
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: udp.c,v 1.12 2002/07/31 20:56:50 sam Exp $
*
* Authors: Christophe Massiot <massiot@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
*****************************************************************************/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( _MSC_VER ) && defined( _WIN32 )
# include <io.h>
#endif
#include "network.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("raw UDP access module") );
set_capability( "access", 0 );
add_shortcut( "udpstream" );
add_shortcut( "udp4" );
add_shortcut( "udp6" );
set_callbacks( Open, __input_FDNetworkClose );
vlc_module_end();
/*****************************************************************************
* Open: open the socket
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
input_socket_t * p_access_data;
module_t * p_network;
char * psz_network = "";
char * psz_name = strdup(p_input->psz_name);
char * psz_parser = psz_name;
char * psz_server_addr = "";
char * psz_server_port = "";
char * psz_bind_addr = "";
char * psz_bind_port = "";
int i_bind_port = 0, i_server_port = 0;
network_socket_t socket_desc;
if( config_GetInt( p_input, "ipv4" ) )
{
psz_network = "ipv4";
}
if( config_GetInt( p_input, "ipv6" ) )
{
psz_network = "ipv6";
}
if( *p_input->psz_access )
{
/* Find out which shortcut was used */
if( !strncmp( p_input->psz_access, "udp6", 5 ) )
{
psz_network = "ipv6";
}
else if( !strncmp( p_input->psz_access, "udp4", 5 ) )
{
psz_network = "ipv4";
}
}
/* Parse psz_name syntax :
* [serveraddr[:serverport]][@[bindaddr]:[bindport]] */
if( *psz_parser && *psz_parser != '@' )
{
/* Found server */
psz_server_addr = psz_parser;
while( *psz_parser && *psz_parser != ':' && *psz_parser != '@' )
{
if( *psz_parser == '[' )
{
/* IPv6 address */
while( *psz_parser && *psz_parser != ']' )
{
psz_parser++;
}
}
psz_parser++;
}
if( *psz_parser == ':' )
{
/* Found server port */
*psz_parser = '\0'; /* Terminate server name */
psz_parser++;
psz_server_port = psz_parser;
while( *psz_parser && *psz_parser != '@' )
{
psz_parser++;
}
}
}
if( *psz_parser == '@' )
{
/* Found bind address or bind port */
*psz_parser = '\0'; /* Terminate server port or name if necessary */
psz_parser++;
if( *psz_parser && *psz_parser != ':' )
{
/* Found bind address */
psz_bind_addr = psz_parser;
while( *psz_parser && *psz_parser != ':' )
{
if( *psz_parser == '[' )
{
/* IPv6 address */
while( *psz_parser && *psz_parser != ']' )
{
psz_parser++;
}
}
psz_parser++;
}
}
if( *psz_parser == ':' )
{
/* Found bind port */
*psz_parser = '\0'; /* Terminate bind address if necessary */
psz_parser++;
psz_bind_port = psz_parser;
}
}
/* Convert ports format */
if( *psz_server_port )
{
i_server_port = strtol( psz_server_port, &psz_parser, 10 );
if( *psz_parser )
{
msg_Err( p_input, "cannot parse server port near %s", psz_parser );
free(psz_name);
return( -1 );
}
}
if( *psz_bind_port )
{
i_bind_port = strtol( psz_bind_port, &psz_parser, 10 );
if( *psz_parser )
{
msg_Err( p_input, "cannot parse bind port near %s", psz_parser );
free(psz_name);
return( -1 );
}
}
p_input->pf_read = input_FDNetworkRead;
p_input->pf_set_program = input_SetProgram;
p_input->pf_set_area = NULL;
p_input->pf_seek = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_pace_control = 0;
p_input->stream.b_seekable = 0;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
if( *psz_server_addr || i_server_port )
{
msg_Err( p_input, "this UDP syntax is deprecated; the server argument will be");
msg_Err( p_input, "ignored (%s:%d). If you wanted to enter a multicast address",
psz_server_addr, i_server_port);
msg_Err( p_input, "or local port, type : %s:@%s:%d",
*p_input->psz_access ? p_input->psz_access : "udp",
psz_server_addr, i_server_port );
i_server_port = 0;
psz_server_addr = "";
}
msg_Dbg( p_input, "opening server=%s:%d local=%s:%d",
psz_server_addr, i_server_port, psz_bind_addr, i_bind_port );
/* Prepare the network_socket_t structure */
socket_desc.i_type = NETWORK_UDP;
socket_desc.psz_bind_addr = psz_bind_addr;
socket_desc.i_bind_port = i_bind_port;
socket_desc.psz_server_addr = psz_server_addr;
socket_desc.i_server_port = i_server_port;
/* Find an appropriate network module */
p_input->p_private = (void*) &socket_desc;
p_network = module_Need( p_input, "network", psz_network );
free(psz_name);
if( p_network == NULL )
{
return( -1 );
}
module_Unneed( p_input, p_network );
p_access_data = p_input->p_access_data = malloc( sizeof(input_socket_t) );
if( p_access_data == NULL )
{
msg_Err( p_input, "out of memory" );
return( -1 );
}
p_access_data->i_handle = socket_desc.i_handle;
p_input->i_mtu = socket_desc.i_mtu;
return( 0 );
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1 +0,0 @@
alsa_SOURCES = alsa.c

View File

@ -1,420 +0,0 @@
/*****************************************************************************
* alsa.c : alsa plugin for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: alsa.c,v 1.21 2002/07/31 20:56:50 sam Exp $
*
* Authors: Henri Fallon <henri@videolan.org> - Original Author
* Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API
* John Paul Lorenti <jpl31@columbia.edu> - Device selection
*
* 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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* calloc(), malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <alsa/asoundlib.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_thread_t * );
static int GetBufInfo ( aout_thread_t *, int );
static void Play ( aout_thread_t *, byte_t *, int );
static void HandleXrun ( aout_thread_t *);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
add_category_hint( N_("Device"), NULL );
add_string( "alsa-device", NULL, NULL, N_("Name"), NULL );
set_description( _("ALSA audio module") );
set_capability( "audio output", 50 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Preamble
*****************************************************************************/
typedef struct alsa_device_t
{
int i_num;
} alsa_device_t;
typedef struct alsa_card_t
{
int i_num;
} alsa_card_t;
/* here we store plugin dependant informations */
struct aout_sys_t
{
snd_pcm_t * p_alsa_handle;
unsigned long buffer_time;
unsigned long period_time;
unsigned long chunk_size;
unsigned long buffer_size;
unsigned long rate;
unsigned int bytes_per_sample;
unsigned int samples_per_frame;
unsigned int bytes_per_frame;
};
/*****************************************************************************
* Open: create a handle and open an alsa device
*****************************************************************************
* This function opens an alsa device, through the alsa API
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
aout_thread_t *p_aout = (aout_thread_t *)p_this;
/* Allows user to choose which ALSA device to use */
char psz_alsadev[128];
char *psz_device, *psz_userdev;
int i_ret;
/* Allocate structures */
p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
if( p_aout->p_sys == NULL )
{
msg_Err( p_aout, "out of memory" );
return -1;
}
p_aout->pf_setformat = SetFormat;
p_aout->pf_getbufinfo = GetBufInfo;
p_aout->pf_play = Play;
/* Read in ALSA device preferences from configuration */
psz_userdev = config_GetPsz( p_aout, "alsa-device" );
if( psz_userdev )
{
psz_device = psz_userdev;
}
else
{
/* Use the internal logic to decide on the device name */
if( p_aout->i_format != AOUT_FMT_AC3 )
{
psz_device = "default";
}
else
{
unsigned char s[4];
s[0] = IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO;
s[1] = IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER;
s[2] = 0;
s[3] = IEC958_AES3_CON_FS_48000;
sprintf( psz_alsadev,
"iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
s[0], s[1], s[2], s[3] );
psz_device = psz_alsadev;
}
}
/* Open device */
i_ret = snd_pcm_open( &(p_aout->p_sys->p_alsa_handle),
psz_device, SND_PCM_STREAM_PLAYBACK, 0);
if( i_ret != 0 )
{
msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
psz_device, snd_strerror(i_ret) );
if( psz_userdev )
{
free( psz_userdev );
}
return -1;
}
if( psz_userdev )
{
free( psz_userdev );
}
return 0;
}
/*****************************************************************************
* SetFormat : sets the alsa output format
*****************************************************************************
* This function prepares the device, sets the rate, format, the mode
* ( "play as soon as you have data" ), and buffer information.
*****************************************************************************/
static int SetFormat( aout_thread_t *p_aout )
{
int i_rv;
int i_format;
snd_pcm_hw_params_t *p_hw;
snd_pcm_sw_params_t *p_sw;
snd_pcm_hw_params_alloca(&p_hw);
snd_pcm_sw_params_alloca(&p_sw);
/* default value for snd_pcm_hw_params_set_buffer_time_near() */
p_aout->p_sys->buffer_time = AOUT_BUFFER_DURATION;
switch (p_aout->i_format)
{
case AOUT_FMT_S16_LE:
i_format = SND_PCM_FORMAT_S16_LE;
p_aout->p_sys->bytes_per_sample = 2;
break;
case AOUT_FMT_AC3:
i_format = SND_PCM_FORMAT_S16_LE;
p_aout->p_sys->bytes_per_sample = 2;
/* buffer_time must be 500000 to avoid a system crash */
p_aout->p_sys->buffer_time = 500000;
break;
default:
i_format = SND_PCM_FORMAT_S16_BE;
p_aout->p_sys->bytes_per_sample = 2;
break;
}
p_aout->p_sys->samples_per_frame = p_aout->i_channels;
p_aout->p_sys->bytes_per_frame = p_aout->p_sys->samples_per_frame *
p_aout->p_sys->bytes_per_sample;
i_rv = snd_pcm_hw_params_any( p_aout->p_sys->p_alsa_handle, p_hw );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to retrieve initial parameters" );
return -1;
}
i_rv = snd_pcm_hw_params_set_access( p_aout->p_sys->p_alsa_handle, p_hw,
SND_PCM_ACCESS_RW_INTERLEAVED );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set interleaved stream format" );
return -1;
}
i_rv = snd_pcm_hw_params_set_format( p_aout->p_sys->p_alsa_handle,
p_hw, i_format );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set stream sample size and word order" );
return -1;
}
i_rv = snd_pcm_hw_params_set_channels( p_aout->p_sys->p_alsa_handle, p_hw,
p_aout->i_channels );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set number of output channels" );
return -1;
}
i_rv = snd_pcm_hw_params_set_rate_near( p_aout->p_sys->p_alsa_handle, p_hw,
p_aout->i_rate, 0 );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set sample rate" );
return -1;
}
p_aout->p_sys->rate = i_rv;
i_rv = snd_pcm_hw_params_set_buffer_time_near( p_aout->p_sys->p_alsa_handle,
p_hw,
p_aout->p_sys->buffer_time,
0 );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set buffer time" );
return -1;
}
p_aout->p_sys->buffer_time = i_rv;
i_rv = snd_pcm_hw_params_set_period_time_near( p_aout->p_sys->p_alsa_handle,
p_hw, p_aout->p_sys->buffer_time / p_aout->p_sys->bytes_per_frame, 0 );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set period time" );
return -1;
}
p_aout->p_sys->period_time = i_rv;
i_rv = snd_pcm_hw_params(p_aout->p_sys->p_alsa_handle, p_hw);
if (i_rv < 0)
{
msg_Err( p_aout, "unable to set hardware configuration" );
return -1;
}
p_aout->p_sys->chunk_size = snd_pcm_hw_params_get_period_size( p_hw, 0 );
p_aout->p_sys->buffer_size = snd_pcm_hw_params_get_buffer_size( p_hw );
snd_pcm_sw_params_current( p_aout->p_sys->p_alsa_handle, p_sw );
i_rv = snd_pcm_sw_params_set_sleep_min( p_aout->p_sys->p_alsa_handle, p_sw,
0 );
i_rv = snd_pcm_sw_params_set_avail_min( p_aout->p_sys->p_alsa_handle, p_sw,
p_aout->p_sys->chunk_size );
/* Worked with the CVS version but not with 0.9beta3
i_rv = snd_pcm_sw_params_set_start_threshold( p_aout->p_sys->p_alsa_handle,
p_sw, p_aout->p_sys->buffer_size );
i_rv = snd_pcm_sw_params_set_stop_threshold( p_aout->p_sys->p_alsa_handle,
p_sw, p_aout->p_sys->buffer_size);
*/
i_rv = snd_pcm_sw_params( p_aout->p_sys->p_alsa_handle, p_sw );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to set software configuration" );
return -1;
}
return 0;
}
/*****************************************************************************
* HandleXrun : reprepare the output
*****************************************************************************
* When buffer gets empty, the driver goes in "Xrun" state, where it needs
* to be reprepared before playing again
*****************************************************************************/
static void HandleXrun(aout_thread_t *p_aout)
{
int i_rv;
msg_Err( p_aout, "resetting output after buffer underrun" );
// i_rv = snd_pcm_reset( p_aout->p_sys->p_alsa_handle );
i_rv = snd_pcm_prepare( p_aout->p_sys->p_alsa_handle );
if( i_rv < 0 )
{
msg_Err( p_aout, "unable to recover from buffer underrun (%s)",
snd_strerror( i_rv ) );
}
}
/*****************************************************************************
* BufInfo: buffer status query
*****************************************************************************
* This function returns the number of used byte in the queue.
* It also deals with errors : indeed if the device comes to run out
* of data to play, it switches to the "underrun" status. It has to
* be flushed and re-prepared
*****************************************************************************/
static int GetBufInfo( aout_thread_t *p_aout, int i_buffer_limit )
{
snd_pcm_status_t *p_status;
int i_alsa_get_status_returns;
snd_pcm_status_alloca( &p_status );
i_alsa_get_status_returns = snd_pcm_status( p_aout->p_sys->p_alsa_handle,
p_status );
if( i_alsa_get_status_returns )
{
msg_Err( p_aout, "failed getting alsa buffer info (%s)",
snd_strerror ( i_alsa_get_status_returns ) );
return ( -1 );
}
switch( snd_pcm_status_get_state( p_status ) )
{
case SND_PCM_STATE_XRUN :
HandleXrun( p_aout );
break;
case SND_PCM_STATE_OPEN:
case SND_PCM_STATE_PREPARED:
case SND_PCM_STATE_RUNNING:
break;
default:
msg_Err( p_aout, "unhandled condition %i",
snd_pcm_status_get_state( p_status ) );
break;
}
return snd_pcm_status_get_avail(p_status) * p_aout->p_sys->bytes_per_frame;
}
/*****************************************************************************
* Play : plays a sample
*****************************************************************************
* Plays a sample using the snd_pcm_writei function from the alsa API
*****************************************************************************/
static void Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
snd_pcm_uframes_t tot_frames;
snd_pcm_uframes_t frames_left;
snd_pcm_uframes_t rv;
tot_frames = i_size / p_aout->p_sys->bytes_per_frame;
frames_left = tot_frames;
while( frames_left > 0 )
{
rv = snd_pcm_writei( p_aout->p_sys->p_alsa_handle, buffer +
(tot_frames - frames_left) *
p_aout->p_sys->bytes_per_frame, frames_left );
if( (signed int) rv < 0 )
{
msg_Err( p_aout, "failed writing to output (%s)",
snd_strerror( rv ) );
return;
}
frames_left -= rv;
}
}
/*****************************************************************************
* Close: close the Alsa device
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
aout_thread_t *p_aout = (aout_thread_t *)p_this;
int i_close_returns;
i_close_returns = snd_pcm_close( p_aout->p_sys->p_alsa_handle );
if( i_close_returns )
{
msg_Err( p_aout, "failed closing ALSA device (%s)",
snd_strerror( i_close_returns ) );
}
free( p_aout->p_sys );
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1 +0,0 @@
arts_SOURCES = arts.c

View File

@ -1,150 +0,0 @@
/*****************************************************************************
* arts.c : aRts module
*****************************************************************************
* Copyright (C) 2001 VideoLAN
*
* Authors: Emmanuel Blindauer <manu@agat.net>
*
* 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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <fcntl.h> /* open(), O_WRONLY */
#include <string.h> /* strerror() */
#include <unistd.h> /* write(), close() */
#include <stdlib.h> /* calloc(), malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <artsc.h>
/*****************************************************************************
* aout_sys_t: arts audio output method descriptor
*****************************************************************************
* This structure is part of the audio output thread descriptor.
* It describes some arts specific variables.
*****************************************************************************/
struct aout_sys_t
{
arts_stream_t stream;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_thread_t * );
static int GetBufInfo ( aout_thread_t *, int );
static void Play ( aout_thread_t *, byte_t *, int );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("aRts audio module") );
set_capability( "audio output", 50 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Open: initialize arts connection to server
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
aout_thread_t *p_aout = (aout_thread_t *)p_this;
int i_err = 0;
/* Allocate structure */
p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
if( p_aout->p_sys == NULL )
{
msg_Err( p_aout, "out of memory" );
return( 1 );
}
i_err = arts_init();
if (i_err < 0)
{
msg_Err( p_aout, "arts_init failed (%s)", arts_error_text(i_err) );
free( p_aout->p_sys );
return(-1);
}
p_aout->pf_setformat = SetFormat;
p_aout->pf_getbufinfo = GetBufInfo;
p_aout->pf_play = Play;
p_aout->p_sys->stream =
arts_play_stream( p_aout->i_rate, 16, p_aout->i_channels, "vlc" );
return( 0 );
}
/*****************************************************************************
* SetFormat: set the output format
*****************************************************************************/
static int SetFormat( aout_thread_t *p_aout )
{
/*Not ready*/
/* p_aout->i_latency = esd_get_latency(i_fd);*/
p_aout->i_latency = 0;
//msg_Dbg( p_aout, "aout_arts_latency: %d", p_aout->i_latency );
return( 0 );
}
/*****************************************************************************
* GetBufInfo: buffer status query
*****************************************************************************/
static int GetBufInfo( aout_thread_t *p_aout, int i_buffer_limit )
{
/* arbitrary value that should be changed */
return( i_buffer_limit );
}
/*****************************************************************************
* Play: play a sound samples buffer
*****************************************************************************
* This function writes a buffer of i_length bytes in the socket
*****************************************************************************/
static void Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
int i_err = arts_write( p_aout->p_sys->stream, buffer, i_size );
if( i_err < 0 )
{
msg_Err( p_aout, "arts_write failed (%s)", arts_error_text(i_err) );
}
}
/*****************************************************************************
* Close: close the Esound socket
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
aout_thread_t *p_aout = (aout_thread_t *)p_this;
arts_close_stream( p_aout->p_sys->stream );
free( p_aout->p_sys );
}

View File

@ -1,5 +0,0 @@
*.bak
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,2 +0,0 @@
avi_SOURCES = avi.c libioRIFF.c

File diff suppressed because it is too large Load Diff

View File

@ -1,263 +0,0 @@
/*****************************************************************************
* avi.h : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: avi.h,v 1.10 2002/07/23 00:39:16 sam Exp $
* Authors: 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.
*****************************************************************************/
#define MAX_PACKETS_IN_FIFO 2
/* flags for use in <dwFlags> in AVIFileHdr */
#define AVIF_HASINDEX 0x00000010 /* Index at end of file? */
#define AVIF_MUSTUSEINDEX 0x00000020
#define AVIF_ISINTERLEAVED 0x00000100
#define AVIF_TRUSTCKTYPE 0x00000800 /* Use CKType to find key frames? */
#define AVIF_WASCAPTUREFILE 0x00010000
#define AVIF_COPYRIGHTED 0x00020000
/* Flags for index */
#define AVIIF_LIST 0x00000001L /* chunk is a 'LIST' */
#define AVIIF_KEYFRAME 0x00000010L /* this frame is a key frame.*/
#define AVIIF_NOTIME 0x00000100L /* this frame doesn't take any time */
#define AVIIF_COMPUSE 0x0FFF0000L /* these bits are for compressor use */
#define AVIIF_FIXKEYFRAME 0x00001000L /* invented; used to say that
the keyframe flag isn't a true flag
but have to be verified */
/* AVI stuff */
#define FOURCC_RIFF VLC_FOURCC('R','I','F','F')
#define FOURCC_LIST VLC_FOURCC('L','I','S','T')
#define FOURCC_JUNK VLC_FOURCC('J','U','N','K')
#define FOURCC_AVI VLC_FOURCC('A','V','I',' ')
#define FOURCC_WAVE VLC_FOURCC('W','A','V','E')
#define FOURCC_avih VLC_FOURCC('a','v','i','h')
#define FOURCC_hdrl VLC_FOURCC('h','d','r','l')
#define FOURCC_movi VLC_FOURCC('m','o','v','i')
#define FOURCC_idx1 VLC_FOURCC('i','d','x','1')
#define FOURCC_strl VLC_FOURCC('s','t','r','l')
#define FOURCC_strh VLC_FOURCC('s','t','r','h')
#define FOURCC_strf VLC_FOURCC('s','t','r','f')
#define FOURCC_strd VLC_FOURCC('s','t','r','d')
#define FOURCC_rec VLC_FOURCC('r','e','c',' ')
#define FOURCC_auds VLC_FOURCC('a','u','d','s')
#define FOURCC_vids VLC_FOURCC('v','i','d','s')
#define TWOCC_wb VLC_TWOCC('w','b')
#define TWOCC_db VLC_TWOCC('d','b')
#define TWOCC_dc VLC_TWOCC('d','c')
#define TWOCC_pc VLC_TWOCC('p','c')
/* MPEG4 video */
#define FOURCC_DIVX VLC_FOURCC('D','I','V','X')
#define FOURCC_divx VLC_FOURCC('d','i','v','x')
#define FOURCC_DIV1 VLC_FOURCC('D','I','V','1')
#define FOURCC_div1 VLC_FOURCC('d','i','v','1')
#define FOURCC_MP4S VLC_FOURCC('M','P','4','S')
#define FOURCC_mp4s VLC_FOURCC('m','p','4','s')
#define FOURCC_M4S2 VLC_FOURCC('M','4','S','2')
#define FOURCC_m4s2 VLC_FOURCC('m','4','s','2')
#define FOURCC_xvid VLC_FOURCC('x','v','i','d')
#define FOURCC_XVID VLC_FOURCC('X','V','I','D')
#define FOURCC_XviD VLC_FOURCC('X','v','i','D')
#define FOURCC_DX50 VLC_FOURCC('D','X','5','0')
#define FOURCC_mp4v VLC_FOURCC('m','p','4','v')
#define FOURCC_4 VLC_FOURCC( 4, 0, 0, 0 )
/* MSMPEG4 v2 */
#define FOURCC_MPG4 VLC_FOURCC('M','P','G','4')
#define FOURCC_mpg4 VLC_FOURCC('m','p','g','4')
#define FOURCC_DIV2 VLC_FOURCC('D','I','V','2')
#define FOURCC_div2 VLC_FOURCC('d','i','v','2')
#define FOURCC_MP42 VLC_FOURCC('M','P','4','2')
#define FOURCC_mp42 VLC_FOURCC('m','p','4','2')
/* MSMPEG4 v3 / M$ mpeg4 v3 */
#define FOURCC_MPG3 VLC_FOURCC('M','P','G','3')
#define FOURCC_mpg3 VLC_FOURCC('m','p','g','3')
#define FOURCC_div3 VLC_FOURCC('d','i','v','3')
#define FOURCC_MP43 VLC_FOURCC('M','P','4','3')
#define FOURCC_mp43 VLC_FOURCC('m','p','4','3')
/* DivX 3.20 */
#define FOURCC_DIV3 VLC_FOURCC('D','I','V','3')
#define FOURCC_DIV4 VLC_FOURCC('D','I','V','4')
#define FOURCC_div4 VLC_FOURCC('d','i','v','4')
#define FOURCC_DIV5 VLC_FOURCC('D','I','V','5')
#define FOURCC_div5 VLC_FOURCC('d','i','v','5')
#define FOURCC_DIV6 VLC_FOURCC('D','I','V','6')
#define FOURCC_div6 VLC_FOURCC('d','i','v','6')
/* AngelPotion stuff */
#define FOURCC_AP41 VLC_FOURCC('A','P','4','1')
/* ?? */
#define FOURCC_3IV1 VLC_FOURCC('3','I','V','1')
/* H263 and H263i */
#define FOURCC_H263 VLC_FOURCC('H','2','6','3')
#define FOURCC_h263 VLC_FOURCC('h','2','6','3')
#define FOURCC_U263 VLC_FOURCC('U','2','6','3')
#define FOURCC_I263 VLC_FOURCC('I','2','6','3')
#define FOURCC_i263 VLC_FOURCC('i','2','6','3')
/* Sound formats */
#define WAVE_FORMAT_UNKNOWN 0x0000
#define WAVE_FORMAT_PCM 0x0001
#define WAVE_FORMAT_MPEG 0x0050
#define WAVE_FORMAT_MPEGLAYER3 0x0055
#define WAVE_FORMAT_AC3 0x2000
typedef struct bitmapinfoheader_s
{
u32 i_size; /* size of header */
u32 i_width;
u32 i_height;
u16 i_planes;
u16 i_bitcount;
u32 i_compression;
u32 i_sizeimage;
u32 i_xpelspermeter;
u32 i_ypelspermeter;
u32 i_clrused;
u32 i_clrimportant;
} bitmapinfoheader_t;
typedef struct waveformatex_s
{
u16 i_formattag;
u16 i_channels;
u32 i_samplespersec;
u32 i_avgbytespersec;
u16 i_blockalign;
u16 i_bitspersample;
u16 i_size; /* the extra size in bytes */
} waveformatex_t;
typedef struct MainAVIHeader_s
{
u32 i_microsecperframe;
u32 i_maxbytespersec;
u32 i_reserved1; /* dwPaddingGranularity; pad to multiples of this
size; normally 2K */
u32 i_flags;
u32 i_totalframes;
u32 i_initialframes;
u32 i_streams;
u32 i_suggestedbuffersize;
u32 i_width;
u32 i_height;
u32 i_scale;
u32 i_rate;
u32 i_start;
u32 i_length;
} MainAVIHeader_t;
typedef struct AVIStreamHeader_s
{
u32 i_type;
u32 i_handler;
u32 i_flags;
u32 i_reserved1; /* wPriority wLanguage */
u32 i_initialframes;
u32 i_scale;
u32 i_rate;
u32 i_start;
u32 i_length; /* In units above... */
u32 i_suggestedbuffersize;
u32 i_quality;
u32 i_samplesize;
} AVIStreamHeader_t;
typedef struct AVIIndexEntry_s
{
u32 i_id;
u32 i_flags;
u32 i_pos;
u32 i_length;
u32 i_lengthtotal;
} AVIIndexEntry_t;
typedef struct AVIESBuffer_s
{
struct AVIESBuffer_s *p_next;
pes_packet_t *p_pes;
int i_posc;
int i_posb;
} AVIESBuffer_t;
typedef struct AVIStreamInfo_s
{
riffchunk_t *p_strl;
riffchunk_t *p_strh;
riffchunk_t *p_strf;
riffchunk_t *p_strd; /* not used */
AVIStreamHeader_t header;
u8 i_cat; /* AUDIO_ES, VIDEO_ES */
bitmapinfoheader_t video_format;
waveformatex_t audio_format;
es_descriptor_t *p_es;
int b_selected; /* newly selected */
AVIIndexEntry_t *p_index;
int i_idxnb;
int i_idxmax;
int i_idxposc; /* numero of chunk */
int i_idxposb; /* byte in the current chunk */
/* add some buffering */
AVIESBuffer_t *p_pes_first;
AVIESBuffer_t *p_pes_last;
int i_pes_count;
int i_pes_totalsize;
} AVIStreamInfo_t;
typedef struct demux_data_avi_file_s
{
mtime_t i_pcr;
int i_rate;
riffchunk_t *p_riff;
riffchunk_t *p_hdrl;
riffchunk_t *p_movi;
riffchunk_t *p_idx1;
int b_seekable;
/* Info extrated from avih */
MainAVIHeader_t avih;
/* number of stream and informations*/
int i_streams;
AVIStreamInfo_t **pp_info;
/* current audio and video es */
AVIStreamInfo_t *p_info_video;
AVIStreamInfo_t *p_info_audio;
} demux_data_avi_file_t;

View File

@ -1,442 +0,0 @@
/*****************************************************************************
* libioRIFF.c : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libioRIFF.c,v 1.13 2002/07/23 00:39:16 sam Exp $
* Authors: 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
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/input.h>
#include "video.h"
#include "libioRIFF.h"
static inline u16 __GetWLE( byte_t *p_buff )
{
return( (*p_buff) + ( *(p_buff+1) <<8 ) );
}
static inline u32 __GetDWLE( byte_t *p_buff )
{
return( *(p_buff) + ( *(p_buff+1) <<8 ) +
( *(p_buff+2) <<16 ) + ( *(p_buff+3) <<24 ) );
}
static inline u32 __EVEN( u32 i )
{
return( (i & 1) ? ++i : i );
}
int __RIFF_TellPos( input_thread_t *p_input, u32 *pos )
{
vlc_mutex_lock( &p_input->stream.stream_lock );
*pos= p_input->stream.p_selected_area->i_tell -
( p_input->p_last_data - p_input->p_current_data );
vlc_mutex_unlock( &p_input->stream.stream_lock );
return 0;
}
int __RIFF_SkipBytes(input_thread_t * p_input,int nb)
{
data_packet_t *p_pack;
int i;
int i_rest;
if( ( p_input->stream.b_seekable )&&( p_input->stream.i_method == INPUT_METHOD_FILE ) )
{
u32 i_pos;
__RIFF_TellPos( p_input, &i_pos);
p_input->pf_seek( p_input, (off_t)(i_pos + nb) );
input_AccessReinit( p_input );
}
else
{
msg_Warn( p_input, "cannot seek, it will take times" );
if( nb < 0 ) { return( -1 ); }
i_rest = nb;
while (i_rest != 0 )
{
if ( i_rest >= 4096 )
{
i = input_SplitBuffer( p_input, &p_pack, 4096);
}
else
{
i = input_SplitBuffer( p_input, &p_pack, i_rest);
}
if ( i < 0 ) { return ( -1 ); }
i_rest-=i;
input_DeletePacket( p_input->p_method_data, p_pack);
if( ( i == 0 )&&( i_rest != 0 )) { return( -1 ); }
}
}
return ( 0 );
}
void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t *p_chunk )
{
if( p_chunk != NULL)
{
if( p_chunk->p_data != NULL )
{
input_DeletePacket( p_input->p_method_data, p_chunk->p_data );
}
free( p_chunk );
}
}
riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input)
{
riffchunk_t * p_riff;
int count;
byte_t * p_peek;
if( !(p_riff = malloc( sizeof(riffchunk_t))) )
{
return( NULL );
}
p_riff->p_data = NULL;
/* peek to have the begining, 8+8 get i_8bytes */
if( ( count = input_Peek( p_input, &p_peek, 16 ) ) < 8 )
{
msg_Err( p_input, "cannot peek()" );
free(p_riff);
return( NULL );
}
p_riff->i_id = __GetDWLE( p_peek );
p_riff->i_size =__GetDWLE( p_peek + 4 );
p_riff->i_type = ( count >= 12 ) ? __GetDWLE( p_peek + 8 ) : 0 ;
memset( &p_riff->i_8bytes, 0, 8 );
if( count >= 12 )
{
memcpy( &p_riff->i_8bytes, p_peek + 8, count - 8 );
}
__RIFF_TellPos(p_input, &(p_riff->i_pos) );
return( p_riff );
}
/**************************************************
* Va au chunk juste d'apres si il en a encore *
* -1 si erreur , 1 si y'en a plus *
**************************************************/
int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather)
{
int i_len;
int i_lenfather;
riffchunk_t *p_riff;
if( ( p_riff = RIFF_ReadChunk( p_input ) ) == NULL )
{
msg_Err( p_input, "cannot read chunk" );
return( -1 );
}
i_len = __EVEN( p_riff->i_size );
if ( p_rifffather != NULL )
{
i_lenfather = __EVEN( p_rifffather->i_size );
if ( p_rifffather->i_pos + i_lenfather <= p_riff->i_pos + i_len + 8 )
{
msg_Err( p_input, "next chunk out of bounds" );
free( p_riff );
return( 1 ); /* pas dans nos frontiere */
}
}
if ( __RIFF_SkipBytes( p_input,i_len + 8 ) != 0 )
{
free( p_riff );
msg_Err( p_input, "cannot go to the next chunk" );
return( -1 );
}
free( p_riff );
return( 0 );
}
/****************************************************************
* Permet de rentrer dans un ck RIFF ou LIST *
****************************************************************/
int RIFF_DescendChunk(input_thread_t * p_input)
{
return( __RIFF_SkipBytes(p_input,12) != 0 ? -1 : 0 );
}
/***************************************************************
* Permet de sortir d'un sous chunk et d'aller sur le suivant *
* chunk *
***************************************************************/
int RIFF_AscendChunk(input_thread_t * p_input ,riffchunk_t *p_riff)
{
int i_skip;
u32 i_posactu;
__RIFF_TellPos(p_input, &i_posactu);
i_skip = __EVEN( p_riff->i_pos + p_riff->i_size + 8 ) - i_posactu;
return( (( __RIFF_SkipBytes(p_input,i_skip)) != 0) ? -1 : 0 );
}
/***************************************************************
* Permet de se deplacer jusqu'au premier chunk avec le bon id *
* *************************************************************/
int RIFF_FindChunk(input_thread_t * p_input ,u32 i_id,riffchunk_t *p_rifffather)
{
riffchunk_t *p_riff = NULL;
do
{
if ( p_riff )
{
free(p_riff);
if ( RIFF_NextChunk(p_input ,p_rifffather) != 0 )
{
return( -1 );
}
}
p_riff=RIFF_ReadChunk(p_input);
} while ( ( p_riff )&&( p_riff->i_id != i_id ) );
if ( ( !p_riff )||( p_riff->i_id != i_id ) )
{
return( -1 );
}
free( p_riff );
return( 0 );
}
/*****************************************************************
* Permet de pointer sur la zone de donné du chunk courant *
*****************************************************************/
int RIFF_GoToChunkData(input_thread_t * p_input)
{
return( ( __RIFF_SkipBytes(p_input,8) != 0 ) ? -1 : 0 );
}
int RIFF_LoadChunkData(input_thread_t * p_input,riffchunk_t *p_riff )
{
off_t i_read = __EVEN( p_riff->i_size );
RIFF_GoToChunkData(p_input);
if ( input_SplitBuffer( p_input,
&p_riff->p_data,
i_read ) != i_read )
{
msg_Err( p_input, "cannot read enough data " );
return ( -1 );
}
if( p_riff->i_size&1 )
{
p_riff->p_data->p_payload_end--;
}
return( 0 );
}
int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
pes_packet_t **pp_pes,
int i_size_index)
{
u32 i_read;
data_packet_t *p_data;
riffchunk_t *p_riff;
int i_size;
int b_pad = 0;
if( (p_riff = RIFF_ReadChunk( p_input )) == NULL )
{
*pp_pes = NULL;
return( -1 );
}
RIFF_GoToChunkData(p_input);
*pp_pes = input_NewPES( p_input->p_method_data );
if( *pp_pes == NULL )
{
return( -1 );
}
if( (!p_riff->i_size) || (!i_size_index ) )
{
i_size = __MAX( i_size_index, p_riff->i_size );
}
else
{
i_size = __MIN( p_riff->i_size, i_size_index );
}
if( !p_riff->i_size )
{
p_data = input_NewPacket( p_input->p_method_data, 0 );
(*pp_pes)->p_first = p_data;
(*pp_pes)->p_last = p_data;
(*pp_pes)->i_nb_data = 1;
(*pp_pes)->i_pes_size = 0;
return( 0 );
}
if( i_size&1 )
{
i_size++;
b_pad = 1;
}
do
{
i_read = input_SplitBuffer(p_input, &p_data, i_size -
(*pp_pes)->i_pes_size );
if( i_read < 0 )
{
/* FIXME free on all packets */
return( -1 );
}
if( (*pp_pes)->p_first == NULL )
{
(*pp_pes)->p_first = p_data;
(*pp_pes)->p_last = p_data;
(*pp_pes)->i_nb_data = 1;
(*pp_pes)->i_pes_size = ( p_data->p_payload_end -
p_data->p_payload_start );
}
else
{
(*pp_pes)->p_last->p_next = p_data;
(*pp_pes)->p_last = p_data;
(*pp_pes)->i_nb_data++;
(*pp_pes)->i_pes_size += ( p_data->p_payload_end -
p_data->p_payload_start );
}
} while( ((*pp_pes)->i_pes_size < i_size)&&(i_read != 0) );
if( b_pad )
{
(*pp_pes)->i_pes_size--;
(*pp_pes)->p_last->p_payload_end--;
}
return( 0 );
}
int RIFF_GoToChunk(input_thread_t * p_input, riffchunk_t *p_riff)
{
if( p_input->stream.b_seekable )
{
p_input->pf_seek( p_input, (off_t)p_riff->i_pos );
input_AccessReinit( p_input );
return( 0 );
}
return( -1 );
}
int RIFF_TestFileHeader( input_thread_t * p_input, riffchunk_t ** pp_riff, u32 i_type )
{
if( !( *pp_riff = RIFF_ReadChunk( p_input ) ) )
{
return( -1 );
}
if( (*pp_riff)->i_id != VLC_FOURCC('R','I','F','F')
|| (*pp_riff)->i_type != i_type )
{
free( *pp_riff );
return( -1 );
}
return( 0 );
}
int RIFF_FindAndLoadChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_fmt, u32 i_type )
{
*pp_fmt = NULL;
if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0)
{
return( -1 );
}
if ( ( (*pp_fmt = RIFF_ReadChunk( p_input )) == NULL)
|| ( RIFF_LoadChunkData( p_input, *pp_fmt ) != 0 ) )
{
if( *pp_fmt != NULL )
{
RIFF_DeleteChunk( p_input, *pp_fmt );
}
return( -1 );
}
return( 0 );
}
int RIFF_FindAndGotoDataChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_data, u32 i_type )
{
*pp_data = NULL;
if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0)
{
return( -1 );
}
if ( ( *pp_data = RIFF_ReadChunk( p_input ) ) == NULL )
{
return( -1 );
}
if ( RIFF_GoToChunkData( p_input ) != 0 )
{
RIFF_DeleteChunk( p_input, *pp_data );
return( -1 );
}
return( 0 );
}
int RIFF_FindListChunk( input_thread_t *p_input, riffchunk_t **pp_riff, riffchunk_t *p_rifffather, u32 i_type )
{
int i_ok;
*pp_riff = NULL;
i_ok = 0;
while( i_ok == 0 )
{
if( *pp_riff != NULL )
{
free( *pp_riff );
}
if( RIFF_FindChunk( p_input,
VLC_FOURCC('L','I','S','T'), p_rifffather ) != 0 )
{
return( -1 );
}
*pp_riff = RIFF_ReadChunk( p_input );
if( *pp_riff == NULL )
{
return( -1 );
}
if( (*pp_riff)->i_type != i_type )
{
if( RIFF_NextChunk( p_input, p_rifffather ) != 0 )
{
return( -1 );
}
}
else
{
i_ok = 1;
}
}
return( 0 );
}

View File

@ -1,67 +0,0 @@
/*****************************************************************************
* libioRIFF.h : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libioRIFF.h,v 1.2 2002/06/30 15:07:57 fenrir Exp $
* Authors: 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.
*****************************************************************************/
typedef struct riffchunk_s
{
u32 i_id;
u32 i_size;
u32 i_type;
u32 i_pos;
data_packet_t *p_data;
u64 i_8bytes; /* it's the first 8 bytes after header
used for key frame generation */
} riffchunk_t;
int __RIFF_TellPos( input_thread_t *p_input, u32 *pos );
int __RIFF_SkipBytes(input_thread_t * p_input,int nb);
void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t *p_chunk );
riffchunk_t *RIFF_ReadChunk(input_thread_t * p_input);
int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather);
int RIFF_DescendChunk(input_thread_t * p_input);
int RIFF_AscendChunk(input_thread_t * p_input ,riffchunk_t *p_riff);
int RIFF_FindChunk(input_thread_t * p_input,
u32 i_id,riffchunk_t *p_rifffather);
int RIFF_GoToChunkData(input_thread_t * p_input);
int RIFF_LoadChunkData(input_thread_t * p_input,
riffchunk_t *p_riff );
int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
pes_packet_t **pp_pes,
int i_size_index);
int RIFF_GoToChunk(input_thread_t * p_input,
riffchunk_t *p_riff);
int RIFF_TestFileHeader( input_thread_t * p_input,
riffchunk_t ** pp_riff,
u32 i_type );
int RIFF_FindAndLoadChunk( input_thread_t * p_input,
riffchunk_t *p_riff,
riffchunk_t **pp_fmt,
u32 i_type );
int RIFF_FindAndGotoDataChunk( input_thread_t * p_input,
riffchunk_t *p_riff,
riffchunk_t **pp_data,
u32 i_type );
int RIFF_FindListChunk( input_thread_t *p_input,
riffchunk_t **pp_riff,
riffchunk_t *p_rifffather,
u32 i_type );

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

File diff suppressed because it is too large Load Diff

View File

@ -1,105 +0,0 @@
/*****************************************************************************
* DrawingTidbits.cpp
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: DrawingTidbits.cpp,v 1.2 2001/03/21 13:42:33 sam Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
*
* 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.
*****************************************************************************/
#include <Bitmap.h>
#include <Debug.h>
#include <Screen.h>
#include "DrawingTidbits.h"
inline uchar
ShiftComponent(uchar component, float percent)
{
// change the color by <percent>, make sure we aren't rounding
// off significant bits
if (percent >= 1)
return (uchar)(component * (2 - percent));
else
return (uchar)(255 - percent * (255 - component));
}
rgb_color
ShiftColor(rgb_color color, float percent)
{
rgb_color result = {
ShiftComponent(color.red, percent),
ShiftComponent(color.green, percent),
ShiftComponent(color.blue, percent),
0
};
return result;
}
static bool
CompareColors(const rgb_color a, const rgb_color b)
{
return a.red == b.red
&& a.green == b.green
&& a.blue == b.blue
&& a.alpha == b.alpha;
}
bool
operator==(const rgb_color &a, const rgb_color &b)
{
return CompareColors(a, b);
}
bool
operator!=(const rgb_color &a, const rgb_color &b)
{
return !CompareColors(a, b);
}
void
ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
{
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
BScreen screen(B_MAIN_SCREEN_ID);
uint32 fromIndex = screen.IndexForColor(from);
uint32 toIndex = screen.IndexForColor(to);
uchar *bits = (uchar *)bitmap->Bits();
int32 bitsLength = bitmap->BitsLength();
for (int32 index = 0; index < bitsLength; index++)
if (bits[index] == fromIndex)
bits[index] = toIndex;
}
void
ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
{
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
BScreen screen(B_MAIN_SCREEN_ID);
uint32 withIndex = screen.IndexForColor(with);
uchar *bits = (uchar *)bitmap->Bits();
int32 bitsLength = bitmap->BitsLength();
for (int32 index = 0; index < bitsLength; index++)
if (bits[index] == B_TRANSPARENT_8_BIT)
bits[index] = withIndex;
}

View File

@ -1,55 +0,0 @@
/*****************************************************************************
* DrawingTidbits.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: DrawingTidbits.h,v 1.2 2001/03/21 13:42:33 sam Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
*
* 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.
*****************************************************************************/
#ifndef __DRAWING_TIBITS__
#define __DRAWING_TIBITS__
#include <GraphicsDefs.h>
rgb_color ShiftColor(rgb_color , float );
bool operator==(const rgb_color &, const rgb_color &);
bool operator!=(const rgb_color &, const rgb_color &);
inline rgb_color
Color(int32 r, int32 g, int32 b, int32 alpha = 255)
{
rgb_color result;
result.red = r;
result.green = g;
result.blue = b;
result.alpha = alpha;
return result;
}
const rgb_color kWhite = { 255, 255, 255, 255};
const rgb_color kBlack = { 0, 0, 0, 255};
const float kDarkness = 1.06;
const float kDimLevel = 0.6;
void ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to);
void ReplaceTransparentColor(BBitmap *bitmap, rgb_color with);
#endif

View File

@ -1,591 +0,0 @@
/*****************************************************************************
* InterfaceWindow.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: InterfaceWindow.cpp,v 1.22 2002/07/23 13:16:51 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tony@castley.net>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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.
*****************************************************************************/
/* System headers */
#include <kernel/OS.h>
#include <InterfaceKit.h>
#include <AppKit.h>
#include <StorageKit.h>
#include <SupportKit.h>
#include <malloc.h>
#include <scsi.h>
#include <scsiprobe_driver.h>
#include <fs_info.h>
#include <string.h>
/* VLC headers */
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <vlc/intf.h>
/* BeOS interface headers */
#include "MsgVals.h"
#include "MediaControlView.h"
#include "PlayListWindow.h"
#include "intf_vlc_wrapper.h"
#include "InterfaceWindow.h"
/*****************************************************************************
* InterfaceWindow
*****************************************************************************/
InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
intf_thread_t *p_interface )
: BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
| B_ASYNCHRONOUS_CONTROLS )
{
file_panel = NULL;
playlist_window = NULL;
p_intf = p_interface;
p_vlc_wrapper = Intf_VLCWrapper::getVLCWrapper(p_intf);
BRect controlRect(0,0,0,0);
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
b_empty_playlist = (p_playlist->i_size < 0);
b_mute = false;
/* set the title bar */
SetName( "interface" );
SetTitle(VOUT_TITLE);
/* set up the main menu */
BMenuBar *menu_bar;
menu_bar = new BMenuBar(controlRect, "main menu");
AddChild( menu_bar );
BMenu *mFile;
BMenu *mAudio;
CDMenu *cd_menu;
BMenu *mNavigation;
/* Add the file Menu */
BMenuItem *mItem;
menu_bar->AddItem( mFile = new BMenu( "File" ) );
menu_bar->ResizeToPreferred();
mFile->AddItem( mItem = new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
new BMessage(OPEN_FILE), 'O') );
cd_menu = new CDMenu( "Open Disc" );
mFile->AddItem( cd_menu );
mFile->AddSeparatorItem();
mFile->AddItem( mItem = new BMenuItem( "Play List" B_UTF8_ELLIPSIS,
new BMessage(OPEN_PLAYLIST), 'P') );
mFile->AddSeparatorItem();
mFile->AddItem( mItem = new BMenuItem( "About" B_UTF8_ELLIPSIS,
new BMessage(B_ABOUT_REQUESTED), 'A') );
mItem->SetTarget( be_app );
mFile->AddItem(mItem = new BMenuItem( "Quit",
new BMessage(B_QUIT_REQUESTED), 'Q') );
/* Add the Audio menu */
menu_bar->AddItem ( mAudio = new BMenu( "Audio" ) );
menu_bar->ResizeToPreferred();
mAudio->AddItem( new LanguageMenu( "Language", AUDIO_ES, p_intf ) );
mAudio->AddItem( new LanguageMenu( "Subtitles", SPU_ES, p_intf ) );
/* Add the Navigation menu */
menu_bar->AddItem( mNavigation = new BMenu( "Navigation" ) );
menu_bar->ResizeToPreferred();
mNavigation->AddItem( new BMenuItem( "Prev Title",
new BMessage(PREV_TITLE)) );
mNavigation->AddItem( new BMenuItem( "Next Title",
new BMessage(NEXT_TITLE)) );
mNavigation->AddItem( new BMenuItem( "Prev Chapter",
new BMessage(PREV_CHAPTER)) );
mNavigation->AddItem( new BMenuItem( "Next Chapter",
new BMessage(NEXT_CHAPTER)) );
ResizeTo(260,50 + menu_bar->Bounds().IntegerHeight()+1);
controlRect = Bounds();
controlRect.top += menu_bar->Bounds().IntegerHeight() + 1;
p_mediaControl = new MediaControlView( controlRect );
p_mediaControl->SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR) );
b_empty_playlist = true;
p_mediaControl->SetEnabled( !b_empty_playlist );
/* Show */
AddChild( p_mediaControl );
Show();
}
InterfaceWindow::~InterfaceWindow()
{
if (playlist_window) playlist_window->ReallyQuit();
}
/*****************************************************************************
* InterfaceWindow::MessageReceived
*****************************************************************************/
void InterfaceWindow::MessageReceived( BMessage * p_message )
{
int vol_val = p_mediaControl->GetVolume(); // remember the current volume
int playback_status; // remember playback state
int i_index;
BAlert *alert;
Activate();
playback_status = p_vlc_wrapper->inputGetStatus();
switch( p_message->what )
{
case B_ABOUT_REQUESTED:
alert = new BAlert(VOUT_TITLE, "BeOS " VOUT_TITLE "\n\n<www.videolan.org>", "Ok");
alert->Go();
break;
case TOGGLE_ON_TOP:
break;
case OPEN_FILE:
if( file_panel )
{
file_panel->Show();
break;
}
file_panel = new BFilePanel();
file_panel->SetTarget( this );
file_panel->Show();
b_empty_playlist = false;
p_mediaControl->SetEnabled( !b_empty_playlist );
break;
case OPEN_PLAYLIST:
{
BRect rect(20,20,320,420);
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_window = PlayListWindow::getPlayList(rect,
"Playlist", p_playlist);
playlist_window->Show();
}
break;
case OPEN_DVD:
{
const char *psz_device;
BString type("dvd");
if( p_message->FindString("device", &psz_device) != B_ERROR )
{
BString device(psz_device);
p_vlc_wrapper->openDisc(type, device, 0,0);
}
}
break;
case STOP_PLAYBACK:
// this currently stops playback not nicely
//p_vlc_wrapper->volume_mute();
//snooze( 400000 );
p_vlc_wrapper->playlistStop();
p_mediaControl->SetStatus(NOT_STARTED_S,DEFAULT_RATE);
break;
case START_PLAYBACK:
/* starts playing in normal mode */
case PAUSE_PLAYBACK:
/* toggle between pause and play */
if( p_intf->p_sys->p_input != NULL )
{
/* pause if currently playing */
if ( playback_status == PLAYING_S )
{
//p_vlc_wrapper->volume_mute();
//snooze( 400000 );
p_vlc_wrapper->playlistPause();
}
else
{
//p_vlc_wrapper->volume_restore();
p_vlc_wrapper->playlistPlay();
}
}
else
{
/* Play a new file */
p_vlc_wrapper->playlistPlay();
}
break;
case FASTER_PLAY:
/* cycle the fast playback modes */
//p_vlc_wrapper->volume_mute();
//snooze( 400000 );
p_vlc_wrapper->playFaster();
break;
case SLOWER_PLAY:
/* cycle the slow playback modes */
//p_vlc_wrapper->volume_mute();
//snooze( 400000 );
p_vlc_wrapper->playSlower();
break;
case SEEK_PLAYBACK:
/* handled by semaphores */
break;
case VOLUME_CHG:
/* adjust the volume */
// vlc_mutex_lock( &p_intf->p_sys->p_input->lock );
// for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
// {
// if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
// {
// p_aout_bank->pp_aout[i_index]->i_savedvolume = vol_val;
// }
// else
// {
// p_aout_bank->pp_aout[i_index]->i_volume = vol_val;
// }
// }
// vlc_mutex_unlock( &p_aout_bank->lock );
break;
case VOLUME_MUTE:
/* toggle muting */
p_vlc_wrapper->toggleMute( );
break;
case SELECT_AUDIO:
{
int32 i = p_message->FindInt32( "audio" );
p_vlc_wrapper->toggleLanguage( i );
}
break;
case SELECT_SUBTITLE:
{
int32 i = p_message->FindInt32( "subtitle" );
p_vlc_wrapper->toggleSubtitle( i );
}
break;
case PREV_TITLE:
{
int i_id;
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
/* Disallow area 0 since it is used for video_ts.vob */
if( i_id > 0 )
{
p_vlc_wrapper->toggleTitle(i_id);
}
break;
}
case NEXT_TITLE:
{
int i_id;
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
{
p_vlc_wrapper->toggleTitle(i_id);
}
}
break;
case PREV_CHAPTER:
{
int i_id;
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_part - 1;
if( i_id >= 0 )
{
p_vlc_wrapper->toggleChapter(i_id);
}
}
break;
case NEXT_CHAPTER:
{
int i_id;
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_part + 1;
if( i_id >= 0 )
{
p_vlc_wrapper->toggleChapter(i_id);
}
}
break;
case B_REFS_RECEIVED:
case B_SIMPLE_DATA:
{
entry_ref ref;
BList* files = new BList();
int i = 0;
while( p_message->FindRef( "refs", i, &ref ) == B_OK )
{
BPath path( &ref );
files->AddItem(new BString((char*)path.Path()) );
i++;
}
p_vlc_wrapper->openFiles(files);
delete files;
}
break;
default:
BWindow::MessageReceived( p_message );
break;
}
}
/*****************************************************************************
* InterfaceWindow::updateInterface
*****************************************************************************/
void InterfaceWindow::updateInterface()
{
if ( p_intf->p_sys->p_input != NULL )
{
if ( acquire_sem(p_mediaControl->fScrubSem) == B_OK )
{
p_vlc_wrapper->setTimeAsFloat(p_mediaControl->GetSeekTo());
}
else if( Lock() )
{
p_mediaControl->SetStatus(p_intf->p_sys->p_input->stream.control.i_status,
p_intf->p_sys->p_input->stream.control.i_rate);
p_mediaControl->SetProgress(p_intf->p_sys->p_input->stream.p_selected_area->i_tell,
p_intf->p_sys->p_input->stream.p_selected_area->i_size);
Unlock();
}
}
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if ( b_empty_playlist != (p_playlist->i_size < 1) )
{
if (Lock())
{
b_empty_playlist = !b_empty_playlist;
p_mediaControl->SetEnabled( !b_empty_playlist );
Unlock();
}
}
}
/*****************************************************************************
* InterfaceWindow::QuitRequested
*****************************************************************************/
bool InterfaceWindow::QuitRequested()
{
p_intf->p_vlc->b_die = VLC_TRUE;
return( true );
}
/*****************************************************************************
* CDMenu::CDMenu
*****************************************************************************/
CDMenu::CDMenu(const char *name)
: BMenu(name)
{
}
/*****************************************************************************
* CDMenu::~CDMenu
*****************************************************************************/
CDMenu::~CDMenu()
{
}
/*****************************************************************************
* CDMenu::AttachedToWindow
*****************************************************************************/
void CDMenu::AttachedToWindow(void)
{
while (RemoveItem((long int)0) != NULL); // remove all items
GetCD("/dev/disk");
BMenu::AttachedToWindow();
}
/*****************************************************************************
* CDMenu::GetCD
*****************************************************************************/
int CDMenu::GetCD( const char *directory )
{
BVolumeRoster *volRoster;
BVolume *vol;
BDirectory *dir;
int status;
int mounted;
char name[B_FILE_NAME_LENGTH];
fs_info info;
dev_t dev;
volRoster = new BVolumeRoster();
vol = new BVolume();
dir = new BDirectory();
status = volRoster->GetNextVolume(vol);
status = vol->GetRootDirectory(dir);
while (status == B_NO_ERROR)
{
mounted = vol->GetName(name);
if ((mounted == B_OK) && /* Disk is currently Mounted */
(vol->IsReadOnly()) ) /* Disk is read-only */
{
dev = vol->Device();
fs_stat_dev(dev, &info);
device_geometry g;
int i_dev;
i_dev = open( info.device_name, O_RDONLY );
if( i_dev >= 0 )
{
if( ioctl(i_dev, B_GET_GEOMETRY, &g, sizeof(g)) >= 0 )
{
if( g.device_type == B_CD ) //ensure the drive is a CD-ROM
{
BMessage *msg;
msg = new BMessage( OPEN_DVD );
msg->AddString( "device", info.device_name );
BMenuItem *menu_item;
menu_item = new BMenuItem( name, msg );
AddItem( menu_item );
}
close(i_dev);
}
}
}
vol->Unset();
status = volRoster->GetNextVolume(vol);
}
}
/*****************************************************************************
* LanguageMenu::LanguageMenu
*****************************************************************************/
LanguageMenu::LanguageMenu(const char *name, int menu_kind,
intf_thread_t *p_interface)
:BMenu(name)
{
kind = menu_kind;
p_intf = p_interface;
}
/*****************************************************************************
* LanguageMenu::~LanguageMenu
*****************************************************************************/
LanguageMenu::~LanguageMenu()
{
}
/*****************************************************************************
* LanguageMenu::AttachedToWindow
*****************************************************************************/
void LanguageMenu::AttachedToWindow(void)
{
while( RemoveItem((long int)0) != NULL )
{
; // remove all items
}
SetRadioMode(true);
GetChannels();
BMenu::AttachedToWindow();
}
/*****************************************************************************
* LanguageMenu::GetChannels
*****************************************************************************/
int LanguageMenu::GetChannels()
{
char *psz_name;
bool b_active;
BMessage *msg;
int i;
es_descriptor_t *p_es = NULL;
/* Insert the null */
if( kind == SPU_ES ) //audio
{
msg = new BMessage(SELECT_SUBTITLE);
msg->AddInt32("subtitle", -1);
BMenuItem *menu_item;
menu_item = new BMenuItem("None", msg);
AddItem(menu_item);
menu_item->SetMarked(TRUE);
}
if( p_intf->p_sys->p_input == NULL )
{
return 1;
}
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
for( i = 0; i < p_intf->p_sys->p_input->stream.i_selected_es_number; i++ )
{
if( kind == p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat )
{
p_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
}
}
for( i = 0; i < p_intf->p_sys->p_input->stream.i_es_number; i++ )
{
if( kind == p_intf->p_sys->p_input->stream.pp_es[i]->i_cat )
{
psz_name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
if( kind == AUDIO_ES ) //audio
{
msg = new BMessage(SELECT_AUDIO);
msg->AddInt32("audio", i);
}
else
{
msg = new BMessage(SELECT_SUBTITLE);
msg->AddInt32("subtitle", i);
}
BMenuItem *menu_item;
menu_item = new BMenuItem(psz_name, msg);
AddItem(menu_item);
b_active = (p_es == p_intf->p_sys->p_input->stream.pp_es[i]);
menu_item->SetMarked(b_active);
}
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}

View File

@ -1,77 +0,0 @@
/*****************************************************************************
* InterfaceWindow.h: BeOS interface window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: InterfaceWindow.h,v 1.15 2002/07/23 12:42:17 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* intf_sys_t: description and status of FB interface
*****************************************************************************/
class MediaControlView;
class PlayListWindow;
class CDMenu : public BMenu
{
public:
CDMenu(const char *name);
~CDMenu();
void AttachedToWindow(void);
private:
int GetCD(const char *directory);
};
class LanguageMenu : public BMenu
{
public:
LanguageMenu(const char *name, int menu_kind,
intf_thread_t *p_interface);
~LanguageMenu();
void AttachedToWindow(void);
private:
intf_thread_t *p_intf;
int kind;
int GetChannels();
};
class InterfaceWindow : public BWindow
{
public:
InterfaceWindow( BRect frame, const char *name,
intf_thread_t *p_interface );
~InterfaceWindow();
// standard window member
virtual bool QuitRequested();
virtual void MessageReceived(BMessage *message);
void updateInterface();
MediaControlView *p_mediaControl;
private:
intf_thread_t *p_intf;
bool b_empty_playlist;
bool b_mute;
BFilePanel *file_panel;
PlayListWindow* playlist_window;
BMenuItem *miOnTop;
Intf_VLCWrapper * p_vlc_wrapper;
};

View File

@ -1 +0,0 @@
beos_SOURCES = beos.cpp aout_beos.cpp vout_beos.cpp intf_beos.cpp InterfaceWindow.cpp DrawingTidbits.cpp TransportButton.cpp PlayListWindow.cpp MediaControlView.cpp intf_vlc_wrapper.cpp

View File

@ -1,287 +0,0 @@
/*****************************************************************************
* MediaControlView.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: MediaControlView.cpp,v 1.8 2002/06/01 12:31:58 sam Exp $
*
* Authors: Tony Castley <tony@castley.net>
*
* 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.
*****************************************************************************/
/* System headers */
#include <InterfaceKit.h>
#include <AppKit.h>
#include <string.h>
/* VLC headers */
#include <vlc/vlc.h>
#include <vlc/intf.h>
/* BeOS interface headers */
#include "MsgVals.h"
#include "Bitmaps.h"
#include "TransportButton.h"
#include "MediaControlView.h"
MediaControlView::MediaControlView( BRect frame )
: BBox( frame, NULL, B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER )
{
float xStart = HORZ_SPACE;
float yStart = VERT_SPACE;
fScrubSem = B_ERROR;
BRect controlRect = BRect(xStart,yStart,
frame.Width() - (HORZ_SPACE * 2), 15);
/* Seek Status */
rgb_color fill_color = {0,255,0};
p_seek = new SeekSlider(controlRect, this, 0, 100, B_TRIANGLE_THUMB);
p_seek->SetValue(0);
p_seek->UseFillColor(true, &fill_color);
AddChild( p_seek );
yStart += 15 + VERT_SPACE;
/* Buttons */
/* Slow play */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kSkipButtonSize);
xStart += kRewindBitmapWidth;
p_slow = new TransportButton(controlRect, B_EMPTY_STRING,
kSkipBackBitmapBits,
kPressedSkipBackBitmapBits,
kDisabledSkipBackBitmapBits,
new BMessage(SLOWER_PLAY));
AddChild( p_slow );
/* Play Pause */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kPlayButtonSize);
xStart += kPlayPauseBitmapWidth + 1.0;
p_play = new PlayPauseButton(controlRect, B_EMPTY_STRING,
kPlayButtonBitmapBits,
kPressedPlayButtonBitmapBits,
kDisabledPlayButtonBitmapBits,
kPlayingPlayButtonBitmapBits,
kPressedPlayingPlayButtonBitmapBits,
kPausedPlayButtonBitmapBits,
kPressedPausedPlayButtonBitmapBits,
new BMessage(START_PLAYBACK));
AddChild( p_play );
/* Fast Foward */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kSkipButtonSize);
xStart += kRewindBitmapWidth;
p_fast = new TransportButton(controlRect, B_EMPTY_STRING,
kSkipForwardBitmapBits,
kPressedSkipForwardBitmapBits,
kDisabledSkipForwardBitmapBits,
new BMessage(FASTER_PLAY));
AddChild( p_fast );
/* Stop */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kStopButtonSize);
xStart += kStopBitmapWidth;
p_stop = new TransportButton(controlRect, B_EMPTY_STRING,
kStopButtonBitmapBits,
kPressedStopButtonBitmapBits,
kDisabledStopButtonBitmapBits,
new BMessage(STOP_PLAYBACK));
AddChild( p_stop );
controlRect.SetLeftTop(BPoint(xStart + 5, yStart + 6));
controlRect.SetRightBottom(controlRect.LeftTop() + kSpeakerButtonSize);
xStart += kSpeakerIconBitmapWidth;
p_mute = new TransportButton(controlRect, B_EMPTY_STRING,
kSpeakerIconBits,
kPressedSpeakerIconBits,
kSpeakerIconBits,
new BMessage(VOLUME_MUTE));
AddChild( p_mute );
/* Volume Slider */
p_vol = new MediaSlider(BRect(xStart,20,255,30), new BMessage(VOLUME_CHG),
0, VOLUME_MAX);
p_vol->SetValue(VOLUME_DEFAULT);
p_vol->UseFillColor(true, &fill_color);
AddChild( p_vol );
}
MediaControlView::~MediaControlView()
{
}
void MediaControlView::MessageReceived(BMessage *message)
{
}
void MediaControlView::SetProgress(uint64 seek, uint64 size)
{
p_seek->SetPosition((float)seek/size);
}
void MediaControlView::SetStatus(int status, int rate)
{
switch( status )
{
case PLAYING_S:
case FORWARD_S:
case BACKWARD_S:
case START_S:
p_play->SetPlaying();
break;
case PAUSE_S:
p_play->SetPaused();
break;
case UNDEF_S:
case NOT_STARTED_S:
default:
p_play->SetStopped();
break;
}
if ( rate < DEFAULT_RATE )
{
}
}
void MediaControlView::SetEnabled(bool enabled)
{
p_slow->SetEnabled(enabled);
p_play->SetEnabled(enabled);
p_fast->SetEnabled(enabled);
p_stop->SetEnabled(enabled);
p_mute->SetEnabled(enabled);
p_vol->SetEnabled(enabled);
p_seek->SetEnabled(enabled);
}
uint32 MediaControlView::GetSeekTo()
{
return p_seek->seekTo;
}
uint32 MediaControlView::GetVolume()
{
return p_vol->Value();
}
/*****************************************************************************
* MediaSlider
*****************************************************************************/
MediaSlider::MediaSlider( BRect frame, BMessage *p_message,
int32 i_min, int32 i_max )
:BSlider(frame, NULL, NULL, p_message, i_min, i_max )
{
}
MediaSlider::~MediaSlider()
{
}
void MediaSlider::DrawThumb(void)
{
BRect r;
BView *v;
rgb_color black = {0,0,0};
r = ThumbFrame();
v = OffscreenView();
if(IsEnabled())
{
v->SetHighColor(black);
}
else
{
v->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
}
r.InsetBy(r.IntegerWidth()/4, r.IntegerHeight()/(4 * r.IntegerWidth() / r.IntegerHeight()));
v->StrokeEllipse(r);
if(IsEnabled())
{
v->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
else
{
v->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
}
r.InsetBy(1,1);
v->FillEllipse(r);
}
/*****************************************************************************
* SeekSlider
*****************************************************************************/
SeekSlider::SeekSlider( BRect frame, MediaControlView *p_owner, int32 i_min,
int32 i_max, thumb_style thumbType = B_TRIANGLE_THUMB )
:MediaSlider( frame, NULL, i_min, i_max )
{
fOwner = p_owner;
fMouseDown = false;
}
SeekSlider::~SeekSlider()
{
}
/*****************************************************************************
* SeekSlider::MouseDown
*****************************************************************************/
void SeekSlider::MouseDown(BPoint where)
{
BSlider::MouseDown(where);
seekTo = ValueForPoint(where);
fOwner->fScrubSem = create_sem(0, "Vlc::fScrubSem");
release_sem(fOwner->fScrubSem);
fMouseDown = true;
}
/*****************************************************************************
* SeekSlider::MouseUp
*****************************************************************************/
void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
{
BSlider::MouseMoved(where, code, message);
if (!fMouseDown)
return;
seekTo = ValueForPoint(where);
release_sem(fOwner->fScrubSem);
}
/*****************************************************************************
* SeekSlider::MouseUp
*****************************************************************************/
void SeekSlider::MouseUp(BPoint where)
{
BSlider::MouseUp(where);
seekTo = ValueForPoint(where);
delete_sem(fOwner->fScrubSem);
fOwner->fScrubSem = B_ERROR;
fMouseDown = false;
}

View File

@ -1,92 +0,0 @@
/*****************************************************************************
* MediaControlView.h: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: MediaControlView.h,v 1.2 2001/09/12 01:31:37 tcastley Exp $
*
* Authors: Tony Castley <tony@castley.net>
*
* 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.
*****************************************************************************/
#define HORZ_SPACE 5.0
#define VERT_SPACE 5.0
class TransportButton;
class PlayPauseButton;
class MediaSlider;
class SeekSlider;
class MediaControlView : public BBox
{
public:
MediaControlView( BRect frame );
~MediaControlView();
virtual void MessageReceived(BMessage *message);
void SetProgress(uint64 seek, uint64 size);
void SetStatus(int status, int rate);
void SetEnabled(bool);
uint32 GetSeekTo();
uint32 GetVolume();
sem_id fScrubSem;
bool fSeeking;
private:
MediaSlider * p_vol;
SeekSlider * p_seek;
TransportButton* p_slow;
PlayPauseButton* p_play;
TransportButton* p_fast;
TransportButton* p_stop;
TransportButton* p_mute;
int current_rate;
int current_status;
};
class MediaSlider : public BSlider
{
public:
MediaSlider(BRect frame,
BMessage *message,
int32 minValue,
int32 maxValue);
~MediaSlider();
virtual void DrawThumb(void);
};
class SeekSlider : public MediaSlider
{
public:
SeekSlider(BRect frame,
MediaControlView *owner,
int32 minValue,
int32 maxValue,
thumb_style thumbType = B_TRIANGLE_THUMB);
~SeekSlider();
uint32 seekTo;
virtual void MouseDown(BPoint);
virtual void MouseUp(BPoint pt);
virtual void MouseMoved(BPoint pt, uint32 c, const BMessage *m);
private:
MediaControlView* fOwner;
bool fMouseDown;
};

View File

@ -1,52 +0,0 @@
/*****************************************************************************
* MsgVals.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: MsgVals.h,v 1.11 2002/07/23 12:42:17 tcastley Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
*
* 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.
*****************************************************************************/
/* MsgVals.h */
#define PLAYING 0
#define PAUSED 1
const uint32 OPEN_FILE = 'OPFL';
const uint32 OPEN_DVD = 'OPDV';
const uint32 OPEN_PLAYLIST = 'OPPL';
const uint32 STOP_PLAYBACK = 'STPL';
const uint32 START_PLAYBACK = 'PLAY';
const uint32 PAUSE_PLAYBACK = 'PAPL';
const uint32 FASTER_PLAY = 'FAPL';
const uint32 SLOWER_PLAY = 'SLPL';
const uint32 SEEK_PLAYBACK = 'SEEK';
const uint32 VOLUME_CHG = 'VOCH';
const uint32 VOLUME_MUTE = 'MUTE';
const uint32 SELECT_AUDIO = 'AUDI';
const uint32 SELECT_SUBTITLE = 'SUBT';
const uint32 PREV_TITLE = 'PRTI';
const uint32 NEXT_TITLE = 'NXTI';
const uint32 PREV_CHAPTER = 'PRCH';
const uint32 NEXT_CHAPTER = 'NXCH';
const uint32 TOGGLE_ON_TOP = 'ONTP';
const uint32 TOGGLE_FULL_SCREEN = 'TGFS';
const uint32 RESIZE_100 = 'RSOR';
const uint32 RESIZE_200 = 'RSDB';
const uint32 ASPECT_CORRECT = 'ASCO';
const uint32 VERT_SYNC = 'VSYN';
const uint32 WINDOW_FEEL = 'WFEL';

View File

@ -1,170 +0,0 @@
/*****************************************************************************
* PlayListWindow.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: PlayListWindow.cpp,v 1.8 2002/08/01 12:36:26 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tony@castley.net>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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.
*****************************************************************************/
/* System headers */
#include <InterfaceKit.h>
#include <StorageKit.h>
#include <SupportKit.h>
#include <string.h>
/* VLC headers */
#include <vlc/vlc.h>
#include <vlc/intf.h>
/* BeOS interface headers */
#include "intf_vlc_wrapper.h"
#include "InterfaceWindow.h"
#include "MsgVals.h"
#include "PlayListWindow.h"
/*****************************************************************************
* PlayListWindow
*****************************************************************************/
PlayListWindow *PlayListWindow::getPlayList( BRect frame, const char *name,
playlist_t *p_pl)
{
static PlayListWindow *one_playlist;
if (one_playlist == NULL)
{
one_playlist = new PlayListWindow(frame, name, p_pl);
}
return one_playlist;
}
PlayListWindow::PlayListWindow( BRect frame, const char *name,
playlist_t *p_pl)
: BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS )
{
SetName( "playlist" );
SetTitle(name);
p_playlist = p_pl;
/* set up the main menu */
BMenuBar *menu_bar;
menu_bar = new BMenuBar(BRect(0,0,0,0), "main menu");
AddChild( menu_bar );
BMenu *mFile;
/* Add the file Menu */
BMenuItem *mItem;
menu_bar->AddItem( mFile = new BMenu( "File" ) );
menu_bar->ResizeToPreferred();
mFile->AddItem( mItem = new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
new BMessage(OPEN_FILE), 'O') );
CDMenu *cd_menu = new CDMenu( "Open Disc" );
mFile->AddItem( cd_menu );
BRect rect = Bounds();
rect.top += menu_bar->Bounds().IntegerHeight() + 1;
BView *p_view = new BView(rect, NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW);
p_listview = new BListView(rect, "PlayList",
B_MULTIPLE_SELECTION_LIST);
for (int i=0; i < p_playlist->i_size; i++)
{
p_listview->AddItem(new BStringItem(p_playlist->pp_items[i]->psz_name));
}
p_view->AddChild(new BScrollView("scroll_playlist", p_listview,
B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true));
AddChild(p_view);
}
PlayListWindow::~PlayListWindow()
{
}
/*****************************************************************************
* PlayListWindow::MessageReceived
*****************************************************************************/
void PlayListWindow::MessageReceived( BMessage * p_message )
{
Activate();
switch( p_message->what )
{
case OPEN_FILE:
if( file_panel )
{
file_panel->Show();
break;
}
file_panel = new BFilePanel();
file_panel->SetTarget( this );
file_panel->Show();
break;
case OPEN_DVD:
{
const char *psz_device;
BString type("dvd");
if( p_message->FindString("device", &psz_device) != B_ERROR )
{
BString device(psz_device);
// p_vlc_wrapper->openDisc(type, device, 0,0);
p_listview->AddItem(new BStringItem(psz_device));
}
}
break;
case B_REFS_RECEIVED:
case B_SIMPLE_DATA:
{
entry_ref ref;
BList* files = new BList();
int i = 0;
while( p_message->FindRef( "refs", i, &ref ) == B_OK )
{
BPath path( &ref );
files->AddItem(new BString((char*)path.Path()) );
p_listview->AddItem(new BStringItem((char*)path.Path()));
i++;
}
// p_vlc_wrapper->openFiles(files);
delete files;
}
break;
default:
BWindow::MessageReceived( p_message );
break;
}
}
bool PlayListWindow::QuitRequested()
{
Hide();
return false;
}
void PlayListWindow::ReallyQuit()
{
Hide();
Lock();
Quit();
}

View File

@ -1,45 +0,0 @@
/*****************************************************************************
* PlayListWindow.h: BeOS interface window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: PlayListWindow.h,v 1.2 2002/06/01 08:54:48 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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.
*****************************************************************************/
class CDMenu;
class PlayListWindow : public BWindow
{
public:
static PlayListWindow *getPlayList(BRect frame, const char *name,
playlist_t *p_pl);
~PlayListWindow();
bool QuitRequested();
void ReallyQuit();
// standard window member
virtual void MessageReceived(BMessage *message);
private:
PlayListWindow( BRect frame, const char *name, playlist_t *p_pl);
playlist_t *p_playlist;
BListView *p_listview;
BFilePanel *file_panel;
};

View File

@ -1,622 +0,0 @@
/*****************************************************************************
* TransportButton.cpp
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: TransportButton.cpp,v 1.3 2001/03/21 13:42:33 sam Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
*
* 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.
*****************************************************************************/
#include <Bitmap.h>
#include <Debug.h>
#include <MessageFilter.h>
#include <Screen.h>
#include <Window.h>
#include <map>
#include "TransportButton.h"
#include "DrawingTidbits.h"
class BitmapStash {
// Bitmap stash is a simple class to hold all the lazily-allocated
// bitmaps that the TransportButton needs when rendering itself.
// signature is a combination of the different enabled, pressed, playing, etc.
// flavors of a bitmap. If the stash does not have a particular bitmap,
// it turns around to ask the button to create one and stores it for next time.
public:
BitmapStash(TransportButton *);
~BitmapStash();
BBitmap *GetBitmap(uint32 signature);
private:
TransportButton *owner;
map<uint32, BBitmap *> stash;
};
BitmapStash::BitmapStash(TransportButton *owner)
: owner(owner)
{
}
BBitmap *
BitmapStash::GetBitmap(uint32 signature)
{
if (stash.find(signature) == stash.end()) {
BBitmap *newBits = owner->MakeBitmap(signature);
ASSERT(newBits);
stash[signature] = newBits;
}
return stash[signature];
}
BitmapStash::~BitmapStash()
{
// delete all the bitmaps
for (map<uint32, BBitmap *>::iterator i = stash.begin(); i != stash.end(); i++)
delete (*i).second;
}
class PeriodicMessageSender {
// used to send a specified message repeatedly when holding down a button
public:
static PeriodicMessageSender *Launch(BMessenger target,
const BMessage *message, bigtime_t period);
void Quit();
private:
PeriodicMessageSender(BMessenger target, const BMessage *message,
bigtime_t period);
~PeriodicMessageSender() {}
// use quit
static status_t TrackBinder(void *);
void Run();
BMessenger target;
BMessage message;
bigtime_t period;
bool requestToQuit;
};
PeriodicMessageSender::PeriodicMessageSender(BMessenger target,
const BMessage *message, bigtime_t period)
: target(target),
message(*message),
period(period),
requestToQuit(false)
{
}
PeriodicMessageSender *
PeriodicMessageSender::Launch(BMessenger target, const BMessage *message,
bigtime_t period)
{
PeriodicMessageSender *result = new PeriodicMessageSender(target, message, period);
thread_id thread = spawn_thread(&PeriodicMessageSender::TrackBinder,
"ButtonRepeatingThread", B_NORMAL_PRIORITY, result);
if (thread <= 0 || resume_thread(thread) != B_OK) {
// didn't start, don't leak self
delete result;
result = 0;
}
return result;
}
void
PeriodicMessageSender::Quit()
{
requestToQuit = true;
}
status_t
PeriodicMessageSender::TrackBinder(void *castToThis)
{
((PeriodicMessageSender *)castToThis)->Run();
return 0;
}
void
PeriodicMessageSender::Run()
{
for (;;) {
snooze(period);
if (requestToQuit)
break;
target.SendMessage(&message);
}
delete this;
}
class SkipButtonKeypressFilter : public BMessageFilter {
public:
SkipButtonKeypressFilter(uint32 shortcutKey, uint32 shortcutModifier,
TransportButton *target);
protected:
filter_result Filter(BMessage *message, BHandler **handler);
private:
uint32 shortcutKey;
uint32 shortcutModifier;
TransportButton *target;
};
SkipButtonKeypressFilter::SkipButtonKeypressFilter(uint32 shortcutKey,
uint32 shortcutModifier, TransportButton *target)
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
shortcutKey(shortcutKey),
shortcutModifier(shortcutModifier),
target(target)
{
}
filter_result
SkipButtonKeypressFilter::Filter(BMessage *message, BHandler **handler)
{
if (target->IsEnabled()
&& (message->what == B_KEY_DOWN || message->what == B_KEY_UP)) {
uint32 modifiers;
uint32 rawKeyChar = 0;
uint8 byte = 0;
int32 key = 0;
if (message->FindInt32("modifiers", (int32 *)&modifiers) != B_OK
|| message->FindInt32("raw_char", (int32 *)&rawKeyChar) != B_OK
|| message->FindInt8("byte", (int8 *)&byte) != B_OK
|| message->FindInt32("key", &key) != B_OK)
return B_DISPATCH_MESSAGE;
modifiers &= B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY
| B_OPTION_KEY | B_MENU_KEY;
// strip caps lock, etc.
if (modifiers == shortcutModifier && rawKeyChar == shortcutKey) {
if (message->what == B_KEY_DOWN)
target->ShortcutKeyDown();
else
target->ShortcutKeyUp();
return B_SKIP_MESSAGE;
}
}
// let others deal with this
return B_DISPATCH_MESSAGE;
}
TransportButton::TransportButton(BRect frame, const char *name,
const unsigned char *normalBits,
const unsigned char *pressedBits,
const unsigned char *disabledBits,
BMessage *invokeMessage, BMessage *startPressingMessage,
BMessage *pressingMessage, BMessage *donePressingMessage, bigtime_t period,
uint32 key, uint32 modifiers, uint32 resizeFlags)
: BControl(frame, name, "", invokeMessage, resizeFlags, B_WILL_DRAW | B_NAVIGABLE),
bitmaps(new BitmapStash(this)),
normalBits(normalBits),
pressedBits(pressedBits),
disabledBits(disabledBits),
startPressingMessage(startPressingMessage),
pressingMessage(pressingMessage),
donePressingMessage(donePressingMessage),
pressingPeriod(period),
mouseDown(false),
keyDown(false),
messageSender(0),
keyPressFilter(0)
{
if (key)
keyPressFilter = new SkipButtonKeypressFilter(key, modifiers, this);
}
void
TransportButton::AttachedToWindow()
{
_inherited::AttachedToWindow();
if (keyPressFilter)
Window()->AddCommonFilter(keyPressFilter);
// transparent to reduce flicker
SetViewColor(B_TRANSPARENT_COLOR);
}
void
TransportButton::DetachedFromWindow()
{
if (keyPressFilter) {
Window()->RemoveCommonFilter(keyPressFilter);
delete keyPressFilter;
}
_inherited::DetachedFromWindow();
}
TransportButton::~TransportButton()
{
delete startPressingMessage;
delete pressingMessage;
delete donePressingMessage;
delete bitmaps;
}
void
TransportButton::WindowActivated(bool state)
{
if (!state)
ShortcutKeyUp();
_inherited::WindowActivated(state);
}
void
TransportButton::SetEnabled(bool on)
{
_inherited::SetEnabled(on);
if (!on)
ShortcutKeyUp();
}
const unsigned char *
TransportButton::BitsForMask(uint32 mask) const
{
switch (mask) {
case 0:
return normalBits;
case kDisabledMask:
return disabledBits;
case kPressedMask:
return pressedBits;
default:
break;
}
TRESPASS();
return 0;
}
BBitmap *
TransportButton::MakeBitmap(uint32 mask)
{
BBitmap *result = new BBitmap(Bounds(), B_COLOR_8_BIT);
result->SetBits(BitsForMask(mask), (Bounds().Width() + 1) * (Bounds().Height() + 1),
0, B_COLOR_8_BIT);
ReplaceTransparentColor(result, Parent()->ViewColor());
return result;
}
uint32
TransportButton::ModeMask() const
{
return (IsEnabled() ? 0 : kDisabledMask)
| (Value() ? kPressedMask : 0);
}
void
TransportButton::Draw(BRect)
{
DrawBitmapAsync(bitmaps->GetBitmap(ModeMask()));
}
void
TransportButton::StartPressing()
{
SetValue(1);
if (startPressingMessage)
Invoke(startPressingMessage);
if (pressingMessage) {
ASSERT(pressingMessage);
messageSender = PeriodicMessageSender::Launch(Messenger(),
pressingMessage, pressingPeriod);
}
}
void
TransportButton::MouseCancelPressing()
{
if (!mouseDown || keyDown)
return;
mouseDown = false;
if (pressingMessage) {
ASSERT(messageSender);
PeriodicMessageSender *sender = messageSender;
messageSender = 0;
sender->Quit();
}
if (donePressingMessage)
Invoke(donePressingMessage);
SetValue(0);
}
void
TransportButton::DonePressing()
{
if (pressingMessage) {
ASSERT(messageSender);
PeriodicMessageSender *sender = messageSender;
messageSender = 0;
sender->Quit();
}
Invoke();
SetValue(0);
}
void
TransportButton::MouseStartPressing()
{
if (mouseDown)
return;
mouseDown = true;
if (!keyDown)
StartPressing();
}
void
TransportButton::MouseDonePressing()
{
if (!mouseDown)
return;
mouseDown = false;
if (!keyDown)
DonePressing();
}
void
TransportButton::ShortcutKeyDown()
{
if (!IsEnabled())
return;
if (keyDown)
return;
keyDown = true;
if (!mouseDown)
StartPressing();
}
void
TransportButton::ShortcutKeyUp()
{
if (!keyDown)
return;
keyDown = false;
if (!mouseDown)
DonePressing();
}
void
TransportButton::MouseDown(BPoint)
{
if (!IsEnabled())
return;
ASSERT(Window()->Flags() & B_ASYNCHRONOUS_CONTROLS);
SetTracking(true);
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
MouseStartPressing();
}
void
TransportButton::MouseMoved(BPoint point, uint32 code, const BMessage *)
{
if (IsTracking() && Bounds().Contains(point) != Value()) {
if (!Value())
MouseStartPressing();
else
MouseCancelPressing();
}
}
void
TransportButton::MouseUp(BPoint point)
{
if (IsTracking()) {
if (Bounds().Contains(point))
MouseDonePressing();
else
MouseCancelPressing();
SetTracking(false);
}
}
void
TransportButton::SetStartPressingMessage(BMessage *message)
{
delete startPressingMessage;
startPressingMessage = message;
}
void
TransportButton::SetPressingMessage(BMessage *message)
{
delete pressingMessage;
pressingMessage = message;
}
void
TransportButton::SetDonePressingMessage(BMessage *message)
{
delete donePressingMessage;
donePressingMessage = message;
}
void
TransportButton::SetPressingPeriod(bigtime_t newTime)
{
pressingPeriod = newTime;
}
PlayPauseButton::PlayPauseButton(BRect frame, const char *name,
const unsigned char *normalBits, const unsigned char *pressedBits,
const unsigned char *disabledBits, const unsigned char *normalPlayingBits,
const unsigned char *pressedPlayingBits, const unsigned char *normalPausedBits,
const unsigned char *pressedPausedBits,
BMessage *invokeMessage, uint32 key, uint32 modifiers, uint32 resizeFlags)
: TransportButton(frame, name, normalBits, pressedBits,
disabledBits, invokeMessage, 0,
0, 0, 0, key, modifiers, resizeFlags),
normalPlayingBits(normalPlayingBits),
pressedPlayingBits(pressedPlayingBits),
normalPausedBits(normalPausedBits),
pressedPausedBits(pressedPausedBits),
state(PlayPauseButton::kStopped),
lastPauseBlinkTime(0),
lastModeMask(0)
{
}
void
PlayPauseButton::SetStopped()
{
if (state == kStopped || state == kAboutToPlay)
return;
state = kStopped;
Invalidate();
}
void
PlayPauseButton::SetPlaying()
{
if (state == kPlaying || state == kAboutToPause)
return;
state = kPlaying;
Invalidate();
}
const bigtime_t kPauseBlinkPeriod = 600000;
void
PlayPauseButton::SetPaused()
{
if (state == kAboutToPlay)
return;
// in paused state blink the LED on and off
bigtime_t now = system_time();
if (state == kPausedLedOn || state == kPausedLedOff) {
if (now - lastPauseBlinkTime < kPauseBlinkPeriod)
return;
if (state == kPausedLedOn)
state = kPausedLedOff;
else
state = kPausedLedOn;
} else
state = kPausedLedOn;
lastPauseBlinkTime = now;
Invalidate();
}
uint32
PlayPauseButton::ModeMask() const
{
if (!IsEnabled())
return kDisabledMask;
uint32 result = 0;
if (Value())
result = kPressedMask;
if (state == kPlaying || state == kAboutToPlay)
result |= kPlayingMask;
else if (state == kAboutToPause || state == kPausedLedOn)
result |= kPausedMask;
return result;
}
const unsigned char *
PlayPauseButton::BitsForMask(uint32 mask) const
{
switch (mask) {
case kPlayingMask:
return normalPlayingBits;
case kPlayingMask | kPressedMask:
return pressedPlayingBits;
case kPausedMask:
return normalPausedBits;
case kPausedMask | kPressedMask:
return pressedPausedBits;
default:
return _inherited::BitsForMask(mask);
}
TRESPASS();
return 0;
}
void
PlayPauseButton::StartPressing()
{
if (state == kPlaying)
state = kAboutToPause;
else
state = kAboutToPlay;
_inherited::StartPressing();
}
void
PlayPauseButton::MouseCancelPressing()
{
if (state == kAboutToPause)
state = kPlaying;
else
state = kStopped;
_inherited::MouseCancelPressing();
}
void
PlayPauseButton::DonePressing()
{
if (state == kAboutToPause) {
state = kPausedLedOn;
lastPauseBlinkTime = system_time();
} else if (state == kAboutToPlay)
state = kPlaying;
_inherited::DonePressing();
}

View File

@ -1,183 +0,0 @@
/*****************************************************************************
* TransportButton.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: TransportButton.h,v 1.3 2001/03/21 13:42:33 sam Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
*
* 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.
*****************************************************************************/
#ifndef __MEDIA_BUTTON__
#define __MEDIA_BUTTON__
#include <Control.h>
class BMessage;
class BBitmap;
class PeriodicMessageSender;
class BitmapStash;
// TransportButton must be installed into a window with B_ASYNCHRONOUS_CONTROLS on
// currently no button focus drawing
class TransportButton : public BControl {
public:
TransportButton(BRect frame, const char *name,
const unsigned char *normalBits,
const unsigned char *pressedBits,
const unsigned char *disabledBits,
BMessage *invokeMessage, // done pressing over button
BMessage *startPressingMessage = 0, // just clicked button
BMessage *pressingMessage = 0, // periodical still pressing
BMessage *donePressing = 0, // tracked out of button/didn't invoke
bigtime_t period = 0, // pressing message period
uint32 key = 0, // optional shortcut key
uint32 modifiers = 0, // optional shortcut key modifier
uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
virtual ~TransportButton();
void SetStartPressingMessage(BMessage *);
void SetPressingMessage(BMessage *);
void SetDonePressingMessage(BMessage *);
void SetPressingPeriod(bigtime_t);
virtual void SetEnabled(bool);
protected:
enum {
kDisabledMask = 0x1,
kPressedMask = 0x2
};
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void Draw(BRect);
virtual void MouseDown(BPoint);
virtual void MouseMoved(BPoint, uint32 code, const BMessage *);
virtual void MouseUp(BPoint);
virtual void WindowActivated(bool);
virtual BBitmap *MakeBitmap(uint32);
// lazy bitmap builder
virtual uint32 ModeMask() const;
// mode mask corresponding to the current button state
// - determines which bitmap will be used
virtual const unsigned char *BitsForMask(uint32) const;
// pick the right bits based on a mode mask
// overriding class can add swapping between two pairs of bitmaps, etc.
virtual void StartPressing();
virtual void MouseCancelPressing();
virtual void DonePressing();
private:
void ShortcutKeyDown();
void ShortcutKeyUp();
void MouseStartPressing();
void MouseDonePressing();
BitmapStash *bitmaps;
// using BitmapStash * here instead of a direct member so that the class can be private in
// the .cpp file
// bitmap bits used to build bitmaps for the different states
const unsigned char *normalBits;
const unsigned char *pressedBits;
const unsigned char *disabledBits;
BMessage *startPressingMessage;
BMessage *pressingMessage;
BMessage *donePressingMessage;
bigtime_t pressingPeriod;
bool mouseDown;
bool keyDown;
PeriodicMessageSender *messageSender;
BMessageFilter *keyPressFilter;
typedef BControl _inherited;
friend class SkipButtonKeypressFilter;
friend class BitmapStash;
};
class PlayPauseButton : public TransportButton {
// Knows about playing and paused states, blinks
// the pause LED during paused state
public:
PlayPauseButton(BRect frame, const char *name,
const unsigned char *normalBits,
const unsigned char *pressedBits,
const unsigned char *disabledBits,
const unsigned char *normalPlayingBits,
const unsigned char *pressedPlayingBits,
const unsigned char *normalPausedBits,
const unsigned char *pressedPausedBits,
BMessage *invokeMessage, // done pressing over button
uint32 key = 0, // optional shortcut key
uint32 modifiers = 0, // optional shortcut key modifier
uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
// These need get called periodically to update the button state
// OK to call them over and over - once the state is correct, the call
// is very low overhead
void SetStopped();
void SetPlaying();
void SetPaused();
protected:
virtual uint32 ModeMask() const;
virtual const unsigned char *BitsForMask(uint32) const;
virtual void StartPressing();
virtual void MouseCancelPressing();
virtual void DonePressing();
private:
const unsigned char *normalPlayingBits;
const unsigned char *pressedPlayingBits;
const unsigned char *normalPausedBits;
const unsigned char *pressedPausedBits;
enum PlayState {
kStopped,
kAboutToPlay,
kPlaying,
kAboutToPause,
kPausedLedOn,
kPausedLedOff
};
enum {
kPlayingMask = 0x4,
kPausedMask = 0x8
};
PlayState state;
bigtime_t lastPauseBlinkTime;
uint32 lastModeMask;
typedef TransportButton _inherited;
};
#endif

View File

@ -1,97 +0,0 @@
/*****************************************************************************
* VideoWindow.h: BeOS video window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: VideoWindow.h,v 1.23 2002/07/23 12:42:17 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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.
*****************************************************************************/
#define BITMAP 0
#define OVERLAY 1
#define OPENGL 2
typedef struct colorcombo
{
color_space colspace;
const char *name;
u32 chroma;
int planes;
int pixel_bytes;
} colorcombo;
colorcombo colspace[]=
{
{B_YCbCr420, "B_YCbCr420", VLC_FOURCC('I','4','2','0'), 3, 2},
{B_YUV422, "B_YUV422", VLC_FOURCC('Y','4','2','2'), 3, 2},
{B_YCbCr422, "B_YCbCr422", VLC_FOURCC('Y','U','Y','2'), 3, 2},
{B_RGB32, "B_RGB32", VLC_FOURCC('R','V','3','2'), 1, 4},
{B_RGB16, "B_RGB16", VLC_FOURCC('R','V','1','6'), 1, 2}
};
#define COLOR_COUNT 5
#define DEFAULT_COL 4
class VLCView : public BView
{
public:
VLCView( BRect bounds);
~VLCView();
void MouseDown(BPoint point);
void Draw(BRect updateRect);
};
class VideoWindow : public BWindow
{
public:
// standard constructor and destructor
VideoWindow( int v_width, int v_height,
BRect frame);
~VideoWindow();
void Zoom(BPoint origin, float width, float height);
void FrameResized(float width, float height);
void FrameMoved(BPoint origin);
void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
void WindowActivated(bool active);
int SelectDrawingMode(int width, int height);
void MessageReceived(BMessage *message);
// this is the hook controling direct screen connection
int32 i_width; // incomming bitmap size
int32 i_height;
BRect winSize; // current window size
bool is_zoomed, vsync;
BBitmap *bitmap[3];
VLCView *view;
int i_buffer;
bool teardownwindow;
thread_id fDrawThreadID;
int mode;
int colspace_index;
private:
vout_thread_t *p_vout;
};

View File

@ -1,201 +0,0 @@
/*****************************************************************************
* aout_beos.cpp: BeOS audio output
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: aout_beos.cpp,v 1.26 2002/07/31 20:56:50 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h> /* malloc(), free() */
#include <kernel/OS.h>
#include <View.h>
#include <Application.h>
#include <Message.h>
#include <Locker.h>
#include <media/MediaDefs.h>
#include <game/PushGameSound.h>
#include <malloc.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/aout.h>
/*****************************************************************************
* aout_sys_t: BeOS audio output method descriptor
*****************************************************************************
* This structure is part of the audio output thread descriptor.
* It describes some BeOS specific variables.
*****************************************************************************/
struct aout_sys_t
{
BPushGameSound * p_sound;
gs_audio_format * p_format;
void * p_buffer;
int i_buffer_size;
int i_buffer_pos;
};
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int SetFormat ( aout_thread_t * );
static int GetBufInfo ( aout_thread_t *, int );
static void Play ( aout_thread_t *, byte_t *, int );
/*****************************************************************************
* OpenAudio: opens a BPushGameSound
*****************************************************************************/
int E_(OpenAudio) ( vlc_object_t *p_this )
{
aout_thread_t * p_aout = (aout_thread_t *)p_this;
/* Allocate structure */
p_aout->p_sys = (aout_sys_t*) malloc( sizeof( aout_sys_t ) );
if( p_aout->p_sys == NULL )
{
msg_Err( p_aout, "out of memory" );
return( 1 );
}
/* Allocate gs_audio_format */
p_aout->p_sys->p_format = (gs_audio_format *) malloc( sizeof( gs_audio_format ) );
if( p_aout->p_sys->p_format == NULL )
{
free( p_aout->p_sys );
msg_Err( p_aout, "out of memory" );
return( 1 );
}
/* Initialize some variables */
p_aout->p_sys->p_format->frame_rate = 44100.0;
p_aout->p_sys->p_format->channel_count = p_aout->i_channels;
p_aout->p_sys->p_format->format = gs_audio_format::B_GS_S16;
p_aout->p_sys->p_format->byte_order = B_MEDIA_LITTLE_ENDIAN;
p_aout->p_sys->p_format->buffer_size = 4*8192;
p_aout->p_sys->i_buffer_pos = 0;
p_aout->pf_setformat = SetFormat;
p_aout->pf_getbufinfo = GetBufInfo;
p_aout->pf_play = Play;
/* Allocate BPushGameSound */
p_aout->p_sys->p_sound = new BPushGameSound( 8192,
p_aout->p_sys->p_format,
2, NULL );
if( p_aout->p_sys->p_sound == NULL )
{
free( p_aout->p_sys->p_format );
free( p_aout->p_sys );
msg_Err( p_aout, "cannot allocate BPushGameSound" );
return( 1 );
}
if( p_aout->p_sys->p_sound->InitCheck() != B_OK )
{
free( p_aout->p_sys->p_format );
free( p_aout->p_sys );
msg_Err( p_aout, "cannot initialize BPushGameSound" );
return( 1 );
}
p_aout->p_sys->p_sound->StartPlaying( );
p_aout->p_sys->p_sound->LockForCyclic( &p_aout->p_sys->p_buffer,
(size_t *)&p_aout->p_sys->i_buffer_size );
return( 0 );
}
/*****************************************************************************
* SetFormat: sets the dsp output format
*****************************************************************************/
static int SetFormat( aout_thread_t *p_aout )
{
return( 0 );
}
/*****************************************************************************
* GetBufInfo: buffer status query
*****************************************************************************/
static int GetBufInfo( aout_thread_t *p_aout, int i_buffer_limit )
{
/* Each value is 4 bytes long (stereo signed 16 bits) */
int i_hard_pos = 4 * p_aout->p_sys->p_sound->CurrentPosition();
i_hard_pos = p_aout->p_sys->i_buffer_pos - i_hard_pos;
if( i_hard_pos < 0 )
{
i_hard_pos += p_aout->p_sys->i_buffer_size;
}
return( i_hard_pos );
}
/*****************************************************************************
* Play: plays a sound samples buffer
*****************************************************************************
* This function writes a buffer of i_length bytes in the dsp
*****************************************************************************/
static void Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
int i_newbuf_pos;
if( (i_newbuf_pos = p_aout->p_sys->i_buffer_pos + i_size)
> p_aout->p_sys->i_buffer_size )
{
memcpy( (void *)((int)p_aout->p_sys->p_buffer
+ p_aout->p_sys->i_buffer_pos),
buffer,
p_aout->p_sys->i_buffer_size - p_aout->p_sys->i_buffer_pos );
memcpy( (void *)((int)p_aout->p_sys->p_buffer),
buffer + p_aout->p_sys->i_buffer_size - p_aout->p_sys->i_buffer_pos,
i_size - ( p_aout->p_sys->i_buffer_size
- p_aout->p_sys->i_buffer_pos ) );
p_aout->p_sys->i_buffer_pos = i_newbuf_pos - p_aout->p_sys->i_buffer_size;
}
else
{
memcpy( (void *)((int)p_aout->p_sys->p_buffer + p_aout->p_sys->i_buffer_pos),
buffer, i_size );
p_aout->p_sys->i_buffer_pos = i_newbuf_pos;
}
}
/*****************************************************************************
* CloseAudio: closes the dsp audio device
*****************************************************************************/
void E_(CloseAudio) ( vlc_object_t *p_this )
{
aout_thread_t * p_aout = (aout_thread_t *)p_this;
p_aout->p_sys->p_sound->UnlockCyclic();
p_aout->p_sys->p_sound->StopPlaying( );
delete p_aout->p_sys->p_sound;
free( p_aout->p_sys->p_format );
free( p_aout->p_sys );
}

View File

@ -1,60 +0,0 @@
/*****************************************************************************
* beos.cpp : BeOS plugin for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: beos.cpp,v 1.20 2002/07/31 20:56:50 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <vlc/vlc.h>
/*****************************************************************************
* External prototypes
*****************************************************************************/
int E_(OpenIntf) ( vlc_object_t * );
void E_(CloseIntf) ( vlc_object_t * );
int E_(OpenAudio) ( vlc_object_t * );
void E_(CloseAudio) ( vlc_object_t * );
int E_(OpenVideo) ( vlc_object_t * );
void E_(CloseVideo) ( vlc_object_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("BeOS standard API module") );
add_submodule();
set_capability( "interface", 100 );
set_callbacks( E_(OpenIntf), E_(CloseIntf) );
add_submodule();
set_capability( "video output", 100 );
set_callbacks( E_(OpenVideo), E_(CloseVideo) );
add_submodule();
set_capability( "audio output", 100 );
set_callbacks( E_(OpenAudio), E_(CloseAudio) );
vlc_module_end();

View File

@ -1,143 +0,0 @@
/*****************************************************************************
* intf_beos.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: intf_beos.cpp,v 1.44 2002/07/31 20:56:50 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tony@castley.net>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h> /* malloc(), free() */
#include <InterfaceKit.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "intf_vlc_wrapper.h"
#include "InterfaceWindow.h"
/*****************************************************************************
* Local prototype
*****************************************************************************/
static void Run ( intf_thread_t *p_intf );
/*****************************************************************************
* OpenIntf: initialize interface
*****************************************************************************/
int E_(OpenIntf) ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*) p_this;
BScreen *screen;
screen = new BScreen();
BRect rect = screen->Frame();
rect.top = rect.bottom-100;
rect.bottom -= 50;
rect.left += 50;
rect.right = rect.left + 350;
delete screen;
/* Allocate instance and initialize some members */
p_intf->p_sys = (intf_sys_t*) malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return( 1 );
}
// p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
p_intf->p_sys->p_input = NULL;
p_intf->pf_run = Run;
/* Create the interface window */
p_intf->p_sys->p_window =
new InterfaceWindow( rect,
VOUT_TITLE " (BeOS interface)", p_intf );
if( p_intf->p_sys->p_window == 0 )
{
free( p_intf->p_sys );
msg_Err( p_intf, "cannot allocate InterfaceWindow" );
return( 1 );
}
return( 0 );
}
/*****************************************************************************
* CloseIntf: destroy interface
*****************************************************************************/
void E_(CloseIntf) ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*) p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
// msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
/* Destroy the interface window */
p_intf->p_sys->p_window->Lock();
p_intf->p_sys->p_window->Quit();
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: event loop
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
while( !p_intf->b_die )
{
/* Update the input */
if( p_intf->p_sys->p_input != NULL )
{
if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
/* Manage the slider */
p_intf->p_sys->p_window->updateInterface();
}
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input =
(input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
FIND_ANYWHERE );
}
/* Wait a bit */
msleep( INTF_IDLE_SLEEP );
}
}

View File

@ -1,459 +0,0 @@
/*****************************************************************************
* intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: intf_vlc_wrapper.cpp,v 1.3 2002/07/23 13:16:51 tcastley Exp $
*
* Authors: Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Tony Casltey <tony@castley.net>
*
* 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.
*****************************************************************************/
/* VLC headers */
#include <SupportKit.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "intf_vlc_wrapper.h"
Intf_VLCWrapper *Intf_VLCWrapper::getVLCWrapper(intf_thread_t *p_if)
{
static Intf_VLCWrapper *one_wrapper;
if (one_wrapper == NULL )
{
one_wrapper = new Intf_VLCWrapper(p_if);
}
return one_wrapper;
}
Intf_VLCWrapper::Intf_VLCWrapper(intf_thread_t *p_if)
{
p_intf = p_if;
}
Intf_VLCWrapper::~Intf_VLCWrapper()
{
}
//bool Intf_VLCWrapper::manage()
//{
//
// p_intf->pf_manage( p_intf );
//
// if ( p_intf->b_die )
// {
// // exit the lot
// return( 1 );
// }
/* Update the input */
// if( p_intf->p_sys->p_input != NULL )
// {
// if( p_intf->p_sys->p_input->b_dead )
// {
// vlc_object_release( p_intf->p_sys->p_input );
// p_intf->p_sys->p_input = NULL;
// }
// }
//
// p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
// FIND_ANYWHERE );
// if ( p_intf->p_sys->p_input != NULL )
// {
// vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
// if( !p_intf->p_sys->p_input->b_die )
// {
// /* New input or stream map change */
// if( p_intf->p_sys->p_input->stream.b_changed ||
// p_intf->p_sys->i_part !=
// p_intf->p_sys->p_input->stream.p_selected_area->i_part )
// {
// setupMenus();
// p_intf->p_sys->b_disabled_menus = 0;
// }
// }
// vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
// }
// else if ( !p_intf->p_sys->b_disabled_menus )
// {
// setupMenus();
// p_intf->p_sys->b_disabled_menus = 1;
// }
// return( 0 );
//}
void Intf_VLCWrapper::quit()
{
p_intf->b_die = 1;
}
/* playlist control */
int Intf_VLCWrapper::inputGetStatus()
{
if( p_intf->p_sys->p_input != NULL )
{
return( p_intf->p_sys->p_input->stream.control.i_status );
}
else
{
return( UNDEF_S );
}
}
bool Intf_VLCWrapper::playlistPlay()
{
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
vlc_mutex_lock( &p_playlist->object_lock );
if( p_playlist->i_size )
{
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play( p_playlist );
vlc_object_release( p_playlist );
}
else
{
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
}
return( true );
}
void Intf_VLCWrapper::playlistPause()
{
toggleMute( );
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Pause( p_playlist );
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::playlistStop()
{
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Stop( p_playlist );
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::playlistNext()
{
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Next( p_playlist );
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::playlistPrev()
{
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Prev( p_playlist );
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::playlistSkip(int i)
{
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Skip( p_playlist, i );
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::playlistGoto(int i)
{
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Goto( p_playlist, i );
vlc_object_release( p_playlist );
}
/* playback control */
void Intf_VLCWrapper::playSlower()
{
if( p_intf->p_sys->p_input != NULL )
{
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
}
if (p_intf->p_sys->p_input->stream.control.i_rate == DEFAULT_RATE)
{
toggleMute( );
}
else
{
toggleMute ( );
}
}
void Intf_VLCWrapper::playFaster()
{
if( p_intf->p_sys->p_input != NULL )
{
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
}
if (p_intf->p_sys->p_input->stream.control.i_rate == DEFAULT_RATE)
{
toggleMute( );
}
else
{
toggleMute ( );
}
}
void Intf_VLCWrapper::toggleProgram(int i_program){}
void Intf_VLCWrapper::toggleTitle(int i_title)
{
if( p_intf->p_sys->p_input != NULL )
{
input_ChangeArea( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.pp_areas[i_title] );
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
//setupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
}
void Intf_VLCWrapper::toggleChapter(int i_chapter)
{
if( p_intf->p_sys->p_input != NULL )
{
p_intf->p_sys->p_input->stream.p_selected_area->i_part = i_chapter;
input_ChangeArea( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.p_selected_area );
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
// setupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
}
void Intf_VLCWrapper::toggleLanguage(int i_language)
{
int32 i_old = -1;
int i_cat = AUDIO_ES;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
for( int i = 0; i < p_intf->p_sys->p_input->stream.i_selected_es_number ; i++ )
{
if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == i_cat )
{
i_old = i;
break;
}
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
msg_Info( p_intf, "Old: %d, New: %d", i_old, i_language);
if( i_language != -1 )
{
input_ToggleES( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.pp_selected_es[i_language],
VLC_TRUE );
}
if( (i_old != -1) && (i_old != i_language) )
{
input_ToggleES( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.pp_selected_es[i_old],
VLC_FALSE );
}
}
void Intf_VLCWrapper::toggleSubtitle(int i_subtitle)
{
int32 i_old = -1;
int i_cat = SPU_ES;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
for( int i = 0; i < p_intf->p_sys->p_input->stream.i_selected_es_number ; i++ )
{
if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == i_cat )
{
i_old = i;
break;
}
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
msg_Info( p_intf, "Old: %d, New: %d", i_old, i_subtitle);
if( i_subtitle != -1 )
{
input_ToggleES( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.pp_selected_es[i_subtitle],
VLC_TRUE );
}
if( (i_old != -1) && (i_old != i_subtitle) )
{
input_ToggleES( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.pp_selected_es[i_old],
VLC_FALSE );
}
}
void Intf_VLCWrapper::channelNext()
{
}
void Intf_VLCWrapper::channelPrev()
{
}
void Intf_VLCWrapper::eject(){}
/* playback info */
BString* Intf_VLCWrapper::getTimeAsString()
{
static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
if( p_intf->p_sys->p_input == NULL )
{
return (new BString("00:00:00"));
}
input_OffsetToTime( p_intf->p_sys->p_input,
psz_currenttime,
p_intf->p_sys->p_input->stream.p_selected_area->i_tell );
return(new BString(psz_currenttime));
}
float Intf_VLCWrapper::getTimeAsFloat()
{
float f_time = 0.0;
if( p_intf->p_sys->p_input != NULL )
{
f_time = (float)p_intf->p_sys->p_input->stream.p_selected_area->i_tell /
(float)p_intf->p_sys->p_input->stream.p_selected_area->i_size;
}
else
{
f_time = 0.0;
}
return( f_time );
}
void Intf_VLCWrapper::setTimeAsFloat(float f_position)
{
if( p_intf->p_sys->p_input != NULL )
{
input_Seek( p_intf->p_sys->p_input,
(long long int)(p_intf->p_sys->p_input->stream.p_selected_area->i_size * f_position / 100),
INPUT_SEEK_SET);
}
}
BList *Intf_VLCWrapper::playlistAsArray()
{
int i;
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
BList* p_list = new BList(p_playlist->i_size);
vlc_mutex_lock( &p_playlist->object_lock );
for( i = 0; i < p_playlist->i_size; i++ )
{
p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
}
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
return( p_list );
}
/* open file/disc/network */
void Intf_VLCWrapper::openFiles(BList *o_files)
{
BString *o_file;
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
while( ( o_file = (BString *)o_files->LastItem() ) )
{
o_files->RemoveItem(o_files->CountItems() - 1);
playlist_Add( p_playlist, o_file->String(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
delete o_file;
}
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
{
BString o_source("");
o_source << o_type << ":" << o_device ;
playlist_t *p_playlist =
(playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
playlist_Add( p_playlist, o_source.String(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
vlc_object_release( p_playlist );
}
void Intf_VLCWrapper::openNet(BString o_addr, int i_port)
{
}
void Intf_VLCWrapper::openNetChannel(BString o_addr, int i_port)
{
}
void Intf_VLCWrapper::openNetHTTP(BString o_addr)
{
}
void Intf_VLCWrapper::toggleMute( )
{
input_ToggleMute( p_intf->p_sys->p_input );
}
/* menus management */

View File

@ -1,121 +0,0 @@
/*****************************************************************************
* intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: intf_vlc_wrapper.h,v 1.3 2002/07/23 13:16:51 tcastley Exp $
*
* Authors: Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Tony Casltey <tony@castley.net>
*
* 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.
*****************************************************************************/
class InterfaceWindow;
/*****************************************************************************
* intf_sys_t: description and status of FB interface
*****************************************************************************/
struct intf_sys_t
{
InterfaceWindow *p_window;
char i_key;
/* The input thread */
input_thread_t * p_input;
/* The messages window */
// msg_subscription_t * p_sub;
/* DVD mode */
vlc_bool_t b_disabled_menus;
vlc_bool_t b_loop;
vlc_bool_t b_mute;
int i_part;
int i_saved_volume;
int i_channel;
};
/* Intf_VLCWrapper is a singleton class
(only one instance at any time) */
class Intf_VLCWrapper
{
public:
static Intf_VLCWrapper *getVLCWrapper(intf_thread_t *p_if);
~Intf_VLCWrapper();
// bool manage();
void quit();
int inputGetStatus();
/* playlist control */
bool playlistPlay();
void playlistPause();
void playlistStop();
void playlistNext();
void playlistPrev();
void playlistSkip(int i);
void playlistGoto(int i);
/* Playback Modes
PLAYLIST_REPEAT_CURRENT
PLAYLIST_FORWARD
PLAYLIST_BACKWARD
PLAYLIST_FORWARD_LOOP
PLAYLIST_BACKWARD_LOOP
PLAYLIST_RANDOM
PLAYLIST_REVERSE_RANDOM
*/
/* Stream Control */
void playSlower();
void playFaster();
/* input control */
int getStatus();
void setStatus(int status);
void inputSeek();
void toggleProgram(int i_program);
void toggleTitle(int i_title);
void toggleChapter(int i_chapter);
void toggleLanguage(int i_language);
void toggleSubtitle(int i_subtitle);
void channelNext();
void channelPrev();
void eject();
/* playback info */
BString* getTimeAsString();
float getTimeAsFloat();
void setTimeAsFloat(float i_offset);
BList* playlistAsArray();
/* open file/disc/network */
void openFiles(BList *o_files);
void openDisc(BString o_type, BString o_device, int i_title, int i_chapter);
void openNet(BString o_addr, int i_port);
void openNetChannel(BString o_addr, int i_port);
void openNetHTTP(BString o_addr);
/* audio stuff */
void toggleMute( );
/* menus management */
void setupMenus();
private:
Intf_VLCWrapper( intf_thread_t *p_if );
es_descriptor_t * p_audio_es;
intf_thread_t *p_intf;
};

View File

@ -1,653 +0,0 @@
/*****************************************************************************
* vout_beos.cpp: beos video output display method
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: vout_beos.cpp,v 1.65 2002/07/31 20:56:50 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* 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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <stdio.h>
#include <string.h> /* strerror() */
#include <InterfaceKit.h>
#include <DirectWindow.h>
#include <Application.h>
#include <Bitmap.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include "VideoWindow.h"
#include "DrawingTidbits.h"
#include "MsgVals.h"
/*****************************************************************************
* vout_sys_t: BeOS video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the BeOS specific properties of an output thread.
*****************************************************************************/
struct vout_sys_t
{
VideoWindow * p_window;
s32 i_width;
s32 i_height;
u32 source_chroma;
int i_index;
};
/*****************************************************************************
* beos_GetAppWindow : retrieve a BWindow pointer from the window name
*****************************************************************************/
BWindow *beos_GetAppWindow(char *name)
{
int32 index;
BWindow *window;
for (index = 0 ; ; index++)
{
window = be_app->WindowAt(index);
if (window == NULL)
break;
if (window->LockWithTimeout(20000) == B_OK)
{
if (strcmp(window->Name(), name) == 0)
{
window->Unlock();
break;
}
window->Unlock();
}
}
return window;
}
/*****************************************************************************
* VideoWindow constructor and destructor
*****************************************************************************/
VideoWindow::VideoWindow( int v_width, int v_height,
BRect frame )
: BWindow( frame, NULL, B_TITLED_WINDOW,
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{
BView *mainView = new BView( Bounds(), "mainView",
B_FOLLOW_ALL, B_FULL_UPDATE_ON_RESIZE);
AddChild(mainView);
mainView->SetViewColor(kBlack);
/* create the view to do the display */
view = new VLCView( Bounds() );
mainView->AddChild(view);
/* set the VideoWindow variables */
teardownwindow = false;
is_zoomed = false;
vsync = false;
i_buffer = 0;
/* call ScreenChanged to set vsync correctly */
BScreen *screen;
display_mode disp_mode;
float refresh;
screen = new BScreen(this);
screen-> GetMode(&disp_mode);
refresh =
(disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
(disp_mode.timing.v_total));
if (refresh < 61)
{
vsync = true;
}
delete screen;
mode = SelectDrawingMode(v_width, v_height);
// remember current settings
i_width = v_width;
i_height = v_height;
FrameResized(v_width, v_height);
if (mode == OVERLAY)
{
overlay_restrictions r;
bitmap[1]->GetOverlayRestrictions(&r);
SetSizeLimits((i_width * r.min_width_scale) + 1, i_width * r.max_width_scale,
(i_height * r.min_height_scale) + 1, i_height * r.max_height_scale);
}
Show();
}
VideoWindow::~VideoWindow()
{
teardownwindow = true;
delete bitmap[0];
delete bitmap[1];
delete bitmap[2];
}
void VideoWindow::MessageReceived( BMessage *p_message )
{
switch( p_message->what )
{
case TOGGLE_FULL_SCREEN:
((BWindow *)this)->Zoom();
break;
case RESIZE_100:
if (is_zoomed)
{
((BWindow *)this)->Zoom();
}
ResizeTo(i_width, i_height);
break;
case RESIZE_200:
if (is_zoomed)
{
((BWindow *)this)->Zoom();
}
ResizeTo(i_width * 2, i_height * 2);
break;
case VERT_SYNC:
vsync = !vsync;
break;
case WINDOW_FEEL:
{
int16 winFeel;
if (p_message->FindInt16("WinFeel", &winFeel) == B_OK)
{
SetFeel((window_feel)winFeel);
}
}
break;
default:
BWindow::MessageReceived( p_message );
break;
}
}
void VideoWindow::drawBuffer(int bufferIndex)
{
i_buffer = bufferIndex;
// sync to the screen if required
if (vsync)
{
BScreen *screen;
screen = new BScreen(this);
screen-> WaitForRetrace(22000);
delete screen;
}
if (LockLooper())
{
// switch the overlay bitmap
if (mode == OVERLAY)
{
rgb_color key;
view->SetViewOverlay(bitmap[i_buffer],
bitmap[i_buffer]->Bounds() ,
view->Bounds(),
&key, B_FOLLOW_ALL,
B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL|
B_OVERLAY_TRANSFER_CHANNEL);
view->SetViewColor(key);
}
else
{
// switch the bitmap
view-> DrawBitmap(bitmap[i_buffer], view->Bounds() );
}
UnlockLooper();
}
}
void VideoWindow::Zoom(BPoint origin, float width, float height )
{
if(is_zoomed)
{
is_zoomed = !is_zoomed;
MoveTo(winSize.left, winSize.top);
ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
be_app->ShowCursor();
}
else
{
is_zoomed = !is_zoomed;
BScreen *screen;
screen = new BScreen(this);
BRect rect = screen->Frame();
delete screen;
MoveTo(0,0);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
be_app->ObscureCursor();
}
}
void VideoWindow::FrameMoved(BPoint origin)
{
if (is_zoomed) return ;
winSize = Frame();
}
void VideoWindow::FrameResized( float width, float height )
{
float out_width, out_height;
float out_left, out_top;
float width_scale = width / i_width;
float height_scale = height / i_height;
if (width_scale <= height_scale)
{
out_width = (i_width * width_scale);
out_height = (i_height * width_scale);
out_left = 0;
out_top = (height - out_height) / 2;
}
else /* if the height is proportionally smaller */
{
out_width = (i_width * height_scale);
out_height = (i_height * height_scale);
out_top = 0;
out_left = (width - out_width) /2;
}
view->MoveTo(out_left,out_top);
view->ResizeTo(out_width, out_height);
if (!is_zoomed)
{
winSize = Frame();
}
}
void VideoWindow::ScreenChanged(BRect frame, color_space mode)
{
BScreen *screen;
float refresh;
screen = new BScreen(this);
display_mode disp_mode;
screen-> GetMode(&disp_mode);
refresh =
(disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
(disp_mode.timing.v_total));
if (refresh < 61)
{
vsync = true;
}
}
void VideoWindow::WindowActivated(bool active)
{
}
int VideoWindow::SelectDrawingMode(int width, int height)
{
int drawingMode = BITMAP;
int noOverlay = 0;
// int noOverlay = !config_GetIntVariable( "overlay" );
for (int i = 0; i < COLOR_COUNT; i++)
{
if (noOverlay) break;
bitmap[0] = new BBitmap ( BRect( 0, 0, width, height ),
B_BITMAP_WILL_OVERLAY,
colspace[i].colspace);
if(bitmap[0] && bitmap[0]->InitCheck() == B_OK)
{
colspace_index = i;
bitmap[1] = new BBitmap( BRect( 0, 0, width, height ), B_BITMAP_WILL_OVERLAY,
colspace[colspace_index].colspace);
bitmap[2] = new BBitmap( BRect( 0, 0, width, height ), B_BITMAP_WILL_OVERLAY,
colspace[colspace_index].colspace);
if ( (bitmap[2] && bitmap[2]->InitCheck() == B_OK) )
{
drawingMode = OVERLAY;
rgb_color key;
view->SetViewOverlay(bitmap[0],
bitmap[0]->Bounds() ,
view->Bounds(),
&key, B_FOLLOW_ALL,
B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
view->SetViewColor(key);
SetTitle(VOUT_TITLE " (Overlay)");
break;
}
else
{
delete bitmap[0];
delete bitmap[1];
delete bitmap[2];
}
}
else
{
delete bitmap[0];
}
}
if (drawingMode == BITMAP)
{
// fallback to RGB16
colspace_index = DEFAULT_COL;
SetTitle(VOUT_TITLE " (Bitmap)");
bitmap[0] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
bitmap[1] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
bitmap[2] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
}
return drawingMode;
}
/*****************************************************************************
* VLCView::VLCView
*****************************************************************************/
VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_NONE,
B_WILL_DRAW)
{
SetViewColor(B_TRANSPARENT_32_BIT);
}
/*****************************************************************************
* VLCView::~VLCView
*****************************************************************************/
VLCView::~VLCView()
{
}
/*****************************************************************************
* VLCVIew::MouseDown
*****************************************************************************/
void VLCView::MouseDown(BPoint point)
{
BMessage* msg = Window()->CurrentMessage();
int32 clicks = msg->FindInt32("clicks");
VideoWindow *vWindow = (VideoWindow *)Window();
uint32 mouseButtons;
BPoint where;
GetMouse(&where, &mouseButtons, true);
if ((mouseButtons & B_PRIMARY_MOUSE_BUTTON) && (clicks == 2))
{
Window()->Zoom();
return;
}
else
{
if (mouseButtons & B_SECONDARY_MOUSE_BUTTON)
{
BPopUpMenu *menu = new BPopUpMenu("context menu");
menu->SetRadioMode(false);
// Toggle FullScreen
BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN));
zoomItem->SetMarked(vWindow->is_zoomed);
menu->AddItem(zoomItem);
// Resize to 100%
BMenuItem *origItem = new BMenuItem("100%", new BMessage(RESIZE_100));
menu->AddItem(origItem);
// Resize to 200%
BMenuItem *doubleItem = new BMenuItem("200%", new BMessage(RESIZE_200));
menu->AddItem(doubleItem);
menu->AddSeparatorItem();
// Toggle vSync
BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC));
vsyncItem->SetMarked(vWindow->vsync);
menu->AddItem(vsyncItem);
menu->AddSeparatorItem();
// Windwo Feel Items
BMessage *winNormFeel = new BMessage(WINDOW_FEEL);
winNormFeel->AddInt16("WinFeel", (int16)B_NORMAL_WINDOW_FEEL);
BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel);
normWindItem->SetMarked(vWindow->Feel() == B_NORMAL_WINDOW_FEEL);
menu->AddItem(normWindItem);
BMessage *winFloatFeel = new BMessage(WINDOW_FEEL);
winFloatFeel->AddInt16("WinFeel", (int16)B_MODAL_ALL_WINDOW_FEEL);
BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel);
onTopWindItem->SetMarked(vWindow->Feel() == B_MODAL_ALL_WINDOW_FEEL);
menu->AddItem(onTopWindItem);
BMessage *winAllFeel = new BMessage(WINDOW_FEEL);
winAllFeel->AddInt16("WinFeel", (int16)B_FLOATING_ALL_WINDOW_FEEL);
BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel);
allSpacesWindItem->SetMarked(vWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL);
menu->AddItem(allSpacesWindItem);
menu->SetTargetForItems(this);
ConvertToScreen(&where);
menu->Go(where, true, false, true);
}
}
}
/*****************************************************************************
* VLCVIew::Draw
*****************************************************************************/
void VLCView::Draw(BRect updateRect)
{
VideoWindow *win = (VideoWindow *) Window();
if (win->mode == BITMAP)
FillRect(updateRect);
}
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Init ( vout_thread_t * );
static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void Display ( vout_thread_t *, picture_t * );
static int BeosOpenDisplay ( vout_thread_t *p_vout );
static void BeosCloseDisplay( vout_thread_t *p_vout );
/*****************************************************************************
* OpenVideo: allocates BeOS video thread output method
*****************************************************************************
* This function allocates and initializes a BeOS vout method.
*****************************************************************************/
int E_(OpenVideo) ( vlc_object_t *p_this )
{
vout_thread_t * p_vout = (vout_thread_t *)p_this;
/* Allocate structure */
p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
msg_Err( p_vout, "out of memory" );
return( 1 );
}
p_vout->p_sys->i_width = p_vout->render.i_width;
p_vout->p_sys->i_height = p_vout->render.i_height;
p_vout->p_sys->source_chroma = p_vout->render.i_chroma;
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = NULL;
p_vout->pf_render = NULL;
p_vout->pf_display = Display;
return( 0 );
}
/*****************************************************************************
* Init: initialize BeOS video thread output method
*****************************************************************************/
int Init( vout_thread_t *p_vout )
{
int i_index;
picture_t *p_pic;
I_OUTPUTPICTURES = 0;
/* Open and initialize device */
if( BeosOpenDisplay( p_vout ) )
{
msg_Err(p_vout, "vout error: can't open display");
return 0;
}
p_vout->output.i_width = p_vout->render.i_width;
p_vout->output.i_height = p_vout->render.i_height;
/* Assume we have square pixels */
p_vout->output.i_aspect = p_vout->p_sys->i_width
* VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
p_vout->output.i_chroma = colspace[p_vout->p_sys->p_window->colspace_index].chroma;
p_vout->p_sys->i_index = 0;
p_vout->b_direct = 1;
p_vout->output.i_rmask = 0x00ff0000;
p_vout->output.i_gmask = 0x0000ff00;
p_vout->output.i_bmask = 0x000000ff;
for (int buffer_index = 0 ; buffer_index < 3; buffer_index++)
{
p_pic = NULL;
/* Find an empty picture slot */
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
p_pic = NULL;
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
if( p_pic == NULL )
{
return 0;
}
p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[buffer_index]->Bits();
p_pic->p->i_lines = p_vout->p_sys->i_height;
p_pic->p->i_pixel_pitch = colspace[p_vout->p_sys->p_window->colspace_index].pixel_bytes;
p_pic->i_planes = colspace[p_vout->p_sys->p_window->colspace_index].planes;
p_pic->p->i_pitch = p_vout->p_sys->p_window->bitmap[buffer_index]->BytesPerRow();
p_pic->p->i_visible_pitch = p_pic->p->i_pixel_pitch * ( p_vout->p_sys->p_window->bitmap[buffer_index]->Bounds().IntegerWidth() + 1 );
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
I_OUTPUTPICTURES++;
}
return( 0 );
}
/*****************************************************************************
* End: terminate BeOS video thread output method
*****************************************************************************/
void End( vout_thread_t *p_vout )
{
BeosCloseDisplay( p_vout );
}
/*****************************************************************************
* CloseVideo: destroy BeOS video thread output method
*****************************************************************************
* Terminate an output method created by DummyCreateOutputMethod
*****************************************************************************/
void E_(CloseVideo) ( vlc_object_t *p_this )
{
vout_thread_t * p_vout = (vout_thread_t *)p_this;
free( p_vout->p_sys );
}
/*****************************************************************************
* Display: displays previously rendered output
*****************************************************************************
* This function send the currently rendered image to BeOS image, waits until
* it is displayed and switch the two rendering buffers, preparing next frame.
*****************************************************************************/
void Display( vout_thread_t *p_vout, picture_t *p_pic )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
/* draw buffer if required */
if (!p_win->teardownwindow)
{
p_win->drawBuffer(p_vout->p_sys->i_index);
}
/* change buffer */
p_vout->p_sys->i_index = ++p_vout->p_sys->i_index % 3;
p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[p_vout->p_sys->i_index]->Bits();
}
/* following functions are local */
/*****************************************************************************
* BeosOpenDisplay: open and initialize BeOS device
*****************************************************************************/
static int BeosOpenDisplay( vout_thread_t *p_vout )
{
p_vout->p_sys->p_window = new VideoWindow( p_vout->p_sys->i_width - 1,
p_vout->p_sys->i_height - 1,
BRect( 20, 50,
20 + p_vout->i_window_width - 1,
50 + p_vout->i_window_height - 1 ));
if( p_vout->p_sys->p_window == NULL )
{
msg_Err( p_vout, "cannot allocate VideoWindow" );
return( 1 );
}
return( 0 );
}
/*****************************************************************************
* BeosDisplay: close and reset BeOS device
*****************************************************************************
* Returns all resources allocated by BeosOpenDisplay and restore the original
* state of the device.
*****************************************************************************/
static void BeosCloseDisplay( vout_thread_t *p_vout )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
/* Destroy the video window */
if( p_win != NULL && !p_win->teardownwindow)
{
p_win->Lock();
p_win->teardownwindow = true;
p_win->Hide();
p_win->Quit();
}
p_win = NULL;
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,8 +0,0 @@
chroma_i420_rgb_SOURCES = i420_rgb.c i420_rgb8.c i420_rgb16.c
chroma_i420_rgb_mmx_SOURCES = i420_rgb.c i420_rgb16.c
chroma_i420_yuy2_SOURCES = i420_yuy2.c
chroma_i420_yuy2_mmx_SOURCES = i420_yuy2.c
chroma_i422_yuy2_SOURCES = i422_yuy2.c
chroma_i422_yuy2_mmx_SOURCES = i422_yuy2.c
chroma_i420_ymga_SOURCES = i420_ymga.c
chroma_i420_ymga_mmx_SOURCES = i420_ymga.c

View File

@ -1,419 +0,0 @@
/*****************************************************************************
* i420_rgb.c : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_rgb.c,v 1.11 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <math.h> /* exp(), pow() */
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "i420_rgb.h"
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
# include "i420_rgb_c.h"
#endif
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Activate ( vlc_object_t * );
static void Deactivate ( vlc_object_t * );
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
static void SetGammaTable ( int *pi_table, double f_gamma );
static void SetYUV ( vout_thread_t * );
static void Set8bppPalette ( vout_thread_t *, u8 * );
#endif
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
vlc_module_begin();
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
set_description( _("I420,IYUV,YV12 to "
"RGB,RV15,RV16,RV24,RV32 conversions") );
set_capability( "chroma", 80 );
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
set_description( _( "MMX I420,IYUV,YV12 to "
"RV15,RV16,RV24,RV32 conversions") );
set_capability( "chroma", 100 );
add_requirement( MMX );
#endif
set_callbacks( Activate, Deactivate );
vlc_module_end();
/*****************************************************************************
* Activate: allocate a chroma function
*****************************************************************************
* This function allocates and initializes a chroma function
*****************************************************************************/
static int Activate( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
size_t i_tables_size;
#endif
if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
{
return -1;
}
switch( p_vout->render.i_chroma )
{
case VLC_FOURCC('Y','V','1','2'):
case VLC_FOURCC('I','4','2','0'):
case VLC_FOURCC('I','Y','U','V'):
switch( p_vout->output.i_chroma )
{
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
case VLC_FOURCC('R','G','B','2'):
p_vout->chroma.pf_convert = E_(I420_RGB8);
break;
#endif
case VLC_FOURCC('R','V','1','5'):
p_vout->chroma.pf_convert = E_(I420_RGB15);
break;
case VLC_FOURCC('R','V','1','6'):
p_vout->chroma.pf_convert = E_(I420_RGB16);
break;
case VLC_FOURCC('R','V','2','4'):
case VLC_FOURCC('R','V','3','2'):
p_vout->chroma.pf_convert = E_(I420_RGB32);
break;
default:
return -1;
}
break;
default:
return -1;
}
p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
if( p_vout->chroma.p_sys == NULL )
{
return -1;
}
switch( p_vout->output.i_chroma )
{
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
case VLC_FOURCC('R','G','B','2'):
p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH );
break;
#endif
case VLC_FOURCC('R','V','1','5'):
case VLC_FOURCC('R','V','1','6'):
p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH * 2 );
break;
case VLC_FOURCC('R','V','2','4'):
case VLC_FOURCC('R','V','3','2'):
p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH * 4 );
break;
default:
p_vout->chroma.p_sys->p_buffer = NULL;
break;
}
if( p_vout->chroma.p_sys->p_buffer == NULL )
{
free( p_vout->chroma.p_sys );
return -1;
}
p_vout->chroma.p_sys->p_offset = malloc( p_vout->output.i_width
* ( ( p_vout->output.i_chroma
== VLC_FOURCC('R','G','B','2') ) ? 2 : 1 )
* sizeof( int ) );
if( p_vout->chroma.p_sys->p_offset == NULL )
{
free( p_vout->chroma.p_sys->p_buffer );
free( p_vout->chroma.p_sys );
return -1;
}
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
switch( p_vout->output.i_chroma )
{
case VLC_FOURCC('R','G','B','2'):
i_tables_size = sizeof( u8 ) * PALETTE_TABLE_SIZE;
break;
case VLC_FOURCC('R','V','1','5'):
case VLC_FOURCC('R','V','1','6'):
i_tables_size = sizeof( u16 ) * RGB_TABLE_SIZE;
break;
default: /* RV24, RV32 */
i_tables_size = sizeof( u32 ) * RGB_TABLE_SIZE;
break;
}
p_vout->chroma.p_sys->p_base = malloc( i_tables_size );
if( p_vout->chroma.p_sys->p_base == NULL )
{
free( p_vout->chroma.p_sys->p_offset );
free( p_vout->chroma.p_sys->p_buffer );
free( p_vout->chroma.p_sys );
return -1;
}
SetYUV( p_vout );
#endif
return 0;
}
/*****************************************************************************
* Deactivate: free the chroma function
*****************************************************************************
* This function frees the previously allocated chroma function
*****************************************************************************/
static void Deactivate( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
free( p_vout->chroma.p_sys->p_base );
#endif
free( p_vout->chroma.p_sys->p_offset );
free( p_vout->chroma.p_sys->p_buffer );
free( p_vout->chroma.p_sys );
}
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
/*****************************************************************************
* SetGammaTable: return intensity table transformed by gamma curve.
*****************************************************************************
* pi_table is a table of 256 entries from 0 to 255.
*****************************************************************************/
static void SetGammaTable( int *pi_table, double f_gamma )
{
int i_y; /* base intensity */
/* Use exp(gamma) instead of gamma */
f_gamma = exp( f_gamma );
/* Build gamma table */
for( i_y = 0; i_y < 256; i_y++ )
{
pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
}
}
/*****************************************************************************
* SetYUV: compute tables and set function pointers
*****************************************************************************/
static void SetYUV( vout_thread_t *p_vout )
{
int pi_gamma[256]; /* gamma table */
int i_index; /* index in tables */
/* Build gamma table */
SetGammaTable( pi_gamma, p_vout->f_gamma );
/*
* Set pointers and build YUV tables
*/
/* Color: build red, green and blue tables */
switch( p_vout->output.i_chroma )
{
case VLC_FOURCC('R','G','B','2'):
p_vout->chroma.p_sys->p_rgb8 = (u8 *)p_vout->chroma.p_sys->p_base;
Set8bppPalette( p_vout, p_vout->chroma.p_sys->p_rgb8 );
break;
case VLC_FOURCC('R','V','1','5'):
case VLC_FOURCC('R','V','1','6'):
p_vout->chroma.p_sys->p_rgb16 = (u16 *)p_vout->chroma.p_sys->p_base;
for( i_index = 0; i_index < RED_MARGIN; i_index++ )
{
p_vout->chroma.p_sys->p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
p_vout->chroma.p_sys->p_rgb16[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
}
for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
{
p_vout->chroma.p_sys->p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
p_vout->chroma.p_sys->p_rgb16[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
}
for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
{
p_vout->chroma.p_sys->p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
p_vout->chroma.p_sys->p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
}
for( i_index = 0; i_index < 256; i_index++ )
{
p_vout->chroma.p_sys->p_rgb16[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
p_vout->chroma.p_sys->p_rgb16[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
p_vout->chroma.p_sys->p_rgb16[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
}
break;
case VLC_FOURCC('R','V','2','4'):
case VLC_FOURCC('R','V','3','2'):
p_vout->chroma.p_sys->p_rgb32 = (u32 *)p_vout->chroma.p_sys->p_base;
for( i_index = 0; i_index < RED_MARGIN; i_index++ )
{
p_vout->chroma.p_sys->p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
p_vout->chroma.p_sys->p_rgb32[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
}
for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
{
p_vout->chroma.p_sys->p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
p_vout->chroma.p_sys->p_rgb32[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
}
for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
{
p_vout->chroma.p_sys->p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
p_vout->chroma.p_sys->p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
}
for( i_index = 0; i_index < 256; i_index++ )
{
p_vout->chroma.p_sys->p_rgb32[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
p_vout->chroma.p_sys->p_rgb32[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
p_vout->chroma.p_sys->p_rgb32[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
}
break;
}
}
static void Set8bppPalette( vout_thread_t *p_vout, u8 *p_rgb8 )
{
#define CLIP( x ) ( ((x < 0) ? 0 : (x > 255) ? 255 : x) << 8 )
int y,u,v;
int r,g,b;
int i = 0, j = 0;
u16 red[ 256 ], green[ 256 ], blue[ 256 ];
unsigned char p_lookup[PALETTE_TABLE_SIZE];
/* This loop calculates the intersection of an YUV box and the RGB cube. */
for ( y = 0; y <= 256; y += 16, i += 128 - 81 )
{
for ( u = 0; u <= 256; u += 32 )
{
for ( v = 0; v <= 256; v += 32 )
{
r = y + ( (V_RED_COEF*(v-128)) >> SHIFT );
g = y + ( (U_GREEN_COEF*(u-128)
+ V_GREEN_COEF*(v-128)) >> SHIFT );
b = y + ( (U_BLUE_COEF*(u-128)) >> SHIFT );
if( r >= 0x00 && g >= 0x00 && b >= 0x00
&& r <= 0xff && g <= 0xff && b <= 0xff )
{
/* This one should never happen unless someone
* fscked up my code */
if( j == 256 )
{
msg_Err( p_vout, "no colors left in palette" );
break;
}
/* Clip the colors */
red[ j ] = CLIP( r );
green[ j ] = CLIP( g );
blue[ j ] = CLIP( b );
/* Allocate color */
p_lookup[ i ] = 1;
p_rgb8[ i++ ] = j;
j++;
}
else
{
p_lookup[ i ] = 0;
p_rgb8[ i++ ] = 0;
}
}
}
}
/* The colors have been allocated, we can set the palette */
p_vout->output.pf_setpalette( p_vout, red, green, blue );
#if 0
/* There will eventually be a way to know which colors
* couldn't be allocated and try to find a replacement */
p_vout->i_white_pixel = 0xff;
p_vout->i_black_pixel = 0x00;
p_vout->i_gray_pixel = 0x44;
p_vout->i_blue_pixel = 0x3b;
#endif
/* This loop allocates colors that got outside the RGB cube */
for ( i = 0, y = 0; y <= 256; y += 16, i += 128 - 81 )
{
for ( u = 0; u <= 256; u += 32 )
{
for ( v = 0; v <= 256; v += 32, i++ )
{
int u2, v2, dist, mindist = 100000000;
if( p_lookup[ i ] || y == 0 )
{
continue;
}
/* Heavy. yeah. */
for( u2 = 0; u2 <= 256; u2 += 32 )
{
for( v2 = 0; v2 <= 256; v2 += 32 )
{
j = ((y>>4)<<7) + (u2>>5)*9 + (v2>>5);
dist = (u-u2)*(u-u2) + (v-v2)*(v-v2);
/* Find the nearest color */
if( p_lookup[ j ] && dist < mindist )
{
p_rgb8[ i ] = p_rgb8[ j ];
mindist = dist;
}
j -= 128;
/* Find the nearest color */
if( p_lookup[ j ] && dist + 128 < mindist )
{
p_rgb8[ i ] = p_rgb8[ j ];
mindist = dist + 128;
}
}
}
}
}
}
}
#endif

View File

@ -1,315 +0,0 @@
/*****************************************************************************
* i420_rgb.h : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: i420_rgb.h,v 1.8 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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.
*****************************************************************************/
/*****************************************************************************
* chroma_sys_t: chroma method descriptor
*****************************************************************************
* This structure is part of the chroma transformation descriptor, it
* describes the yuv2rgb specific properties.
*****************************************************************************/
struct chroma_sys_t
{
u8 *p_buffer;
int *p_offset;
#ifdef MODULE_NAME_IS_chroma_i420_rgb
/* Pre-calculated conversion tables */
void *p_base; /* base for all conversion tables */
u8 *p_rgb8; /* RGB 8 bits table */
u16 *p_rgb16; /* RGB 16 bits table */
u32 *p_rgb32; /* RGB 32 bits table */
#endif
};
/*****************************************************************************
* Prototypes
*****************************************************************************/
#ifdef MODULE_NAME_IS_chroma_i420_rgb
void E_(I420_RGB8) ( vout_thread_t *, picture_t *, picture_t * );
#endif
void E_(I420_RGB15)( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB16)( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB32)( vout_thread_t *, picture_t *, picture_t * );
/*****************************************************************************
* CONVERT_*_PIXEL: pixel conversion macros
*****************************************************************************
* These conversion routines are used by YUV conversion functions.
* conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
* which is also modified. CONVERT_4YUV_PIXEL is used for 8bpp dithering,
* CONVERT_4YUV_PIXEL_SCALE does the same but also scales the output.
*****************************************************************************/
#define CONVERT_Y_PIXEL( BPP ) \
/* Only Y sample is present */ \
p_ybase = p_yuv + *p_y++; \
*p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
+ i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
#define CONVERT_YUV_PIXEL( BPP ) \
/* Y, U and V samples are present */ \
i_uval = *p_u++; \
i_vval = *p_v++; \
i_red = (V_RED_COEF * i_vval) >> SHIFT; \
i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
CONVERT_Y_PIXEL( BPP ) \
#define CONVERT_4YUV_PIXEL( CHROMA ) \
*p_pic++ = p_lookup[ \
(((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither20[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither20[i_real_y]) >> 5) ]; \
*p_pic++ = p_lookup[ \
(((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
+ ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
+ ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
*p_pic++ = p_lookup[ \
(((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither22[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither22[i_real_y]) >> 5) ]; \
*p_pic++ = p_lookup[ \
(((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
+ ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
+ ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
#define CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
*p_pic++ = p_lookup[ \
( ((*p_y + dither10[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither20[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither20[i_real_y]) >> 5) ]; \
p_y += *p_offset++; \
p_u += *p_offset; \
p_v += *p_offset++; \
*p_pic++ = p_lookup[ \
( ((*p_y + dither11[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither21[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither21[i_real_y]) >> 5) ]; \
p_y += *p_offset++; \
p_u += *p_offset; \
p_v += *p_offset++; \
*p_pic++ = p_lookup[ \
( ((*p_y + dither12[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither22[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither22[i_real_y]) >> 5) ]; \
p_y += *p_offset++; \
p_u += *p_offset; \
p_v += *p_offset++; \
*p_pic++ = p_lookup[ \
( ((*p_y + dither13[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither23[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither23[i_real_y]) >> 5) ]; \
p_y += *p_offset++; \
p_u += *p_offset; \
p_v += *p_offset++; \
/*****************************************************************************
* SCALE_WIDTH: scale a line horizontally
*****************************************************************************
* This macro scales a line using rendering buffer and offset array. It works
* for 1, 2 and 4 Bpp.
*****************************************************************************/
#define SCALE_WIDTH \
if( b_hscale ) \
{ \
/* Horizontal scaling, conversion has been done to buffer. \
* Rewind buffer and offset, then copy and scale line */ \
p_buffer = p_buffer_start; \
p_offset = p_offset_start; \
for( i_x = p_vout->output.i_width / 16; i_x--; ) \
{ \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
} \
for( i_x = p_vout->output.i_width & 15; i_x--; ) \
{ \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
} \
p_pic += i_right_margin; \
} \
else \
{ \
/* No scaling, conversion has been done directly in picture memory. \
* Increment of picture pointer to end of line is still needed */ \
(u8*)p_pic += p_dest->p->i_pitch; \
} \
/*****************************************************************************
* SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
*****************************************************************************
* This macro scales a line using an offset array.
*****************************************************************************/
#define SCALE_WIDTH_DITHER( CHROMA ) \
if( b_hscale ) \
{ \
/* Horizontal scaling - we can't use a buffer due to dithering */ \
p_offset = p_offset_start; \
for( i_x = p_vout->output.i_width / 16; i_x--; ) \
{ \
CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
} \
} \
else \
{ \
for( i_x = p_vout->render.i_width / 16; i_x--; ) \
{ \
CONVERT_4YUV_PIXEL( CHROMA ) \
CONVERT_4YUV_PIXEL( CHROMA ) \
CONVERT_4YUV_PIXEL( CHROMA ) \
CONVERT_4YUV_PIXEL( CHROMA ) \
} \
} \
/* Increment of picture pointer to end of line is still needed */ \
p_pic += i_right_margin; \
\
/* Increment the Y coordinate in the matrix, modulo 4 */ \
i_real_y = (i_real_y + 1) & 0x3; \
/*****************************************************************************
* SCALE_HEIGHT: handle vertical scaling
*****************************************************************************
* This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
* 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
* and 4 Bpp.
*****************************************************************************/
#define SCALE_HEIGHT( CHROMA, BPP ) \
/* If line is odd, rewind 4:2:0 U and V samples */ \
if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
} \
\
/* \
* Handle vertical scaling. The current line can be copied or next one \
* can be ignored. \
*/ \
switch( i_vscale ) \
{ \
case -1: /* vertical scaling factor is < 1 */ \
while( (i_scale_count -= p_vout->output.i_height) > 0 ) \
{ \
/* Height reduction: skip next source line */ \
p_y += p_vout->render.i_width; \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
{ \
if( i_y & 0x1 ) \
{ \
p_u += i_chroma_width; \
p_v += i_chroma_width; \
} \
} \
else if( CHROMA == 444 ) \
{ \
p_u += p_vout->render.i_width; \
p_v += p_vout->render.i_width; \
} \
} \
i_scale_count += p_vout->render.i_height; \
break; \
case 1: /* vertical scaling factor is > 1 */ \
while( (i_scale_count -= p_vout->render.i_height) > 0 ) \
{ \
/* Height increment: copy previous picture line */ \
p_vout->p_vlc->pf_memcpy( p_pic, p_pic_start, \
p_vout->output.i_width * BPP ); \
(u8*)p_pic += p_dest->p->i_pitch; \
} \
i_scale_count += p_vout->output.i_height; \
break; \
} \
/*****************************************************************************
* SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
*****************************************************************************
* This macro handles vertical scaling for a picture. CHROMA may be 420,
* 422 or 444 for RGB conversion, or 400 for gray conversion.
*****************************************************************************/
#define SCALE_HEIGHT_DITHER( CHROMA ) \
\
/* If line is odd, rewind 4:2:0 U and V samples */ \
if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
} \
\
/* \
* Handle vertical scaling. The current line can be copied or next one \
* can be ignored. \
*/ \
\
switch( i_vscale ) \
{ \
case -1: /* vertical scaling factor is < 1 */ \
while( (i_scale_count -= p_vout->output.i_height) > 0 ) \
{ \
/* Height reduction: skip next source line */ \
p_y += p_vout->render.i_width; \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
{ \
if( i_y & 0x1 ) \
{ \
p_u += i_chroma_width; \
p_v += i_chroma_width; \
} \
} \
else if( CHROMA == 444 ) \
{ \
p_u += p_vout->render.i_width; \
p_v += p_vout->render.i_width; \
} \
} \
i_scale_count += p_vout->render.i_height; \
break; \
case 1: /* vertical scaling factor is > 1 */ \
while( (i_scale_count -= p_vout->render.i_height) > 0 ) \
{ \
p_y -= p_vout->render.i_width; \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
SCALE_WIDTH_DITHER( CHROMA ); \
} \
i_scale_count += p_vout->output.i_height; \
break; \
} \

View File

@ -1,498 +0,0 @@
/*****************************************************************************
* i420_rgb16.c : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: i420_rgb16.c,v 1.10 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "i420_rgb.h"
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
# include "i420_rgb_c.h"
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
# include "i420_rgb_mmx.h"
#endif
static void SetOffset( int, int, int, int, vlc_bool_t *, int *, int * );
/*****************************************************************************
* I420_RGB15: color YUV 4:2:0 to RGB 15 bpp
*****************************************************************************
* Horizontal alignment needed:
* - input: 8 pixels (8 Y bytes, 4 U/V bytes), margins not allowed
* - output: 1 pixel (2 bytes), margins allowed
* Vertical alignment needed:
* - input: 2 lines (2 Y lines, 1 U/V line)
* - output: 1 line
*****************************************************************************/
void E_(I420_RGB15)( vout_thread_t *p_vout, picture_t *p_src,
picture_t *p_dest )
{
/* We got this one from the old arguments */
u16 *p_pic = (u16*)p_dest->p->p_pixels;
u8 *p_y = p_src->Y_PIXELS;
u8 *p_u = p_src->U_PIXELS;
u8 *p_v = p_src->V_PIXELS;
vlc_bool_t b_hscale; /* horizontal scaling type */
int i_vscale; /* vertical scaling type */
int i_x, i_y; /* horizontal and vertical indexes */
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_vout->render.i_width / 2; /* chroma width */
u16 * p_pic_start; /* beginning of the current line for copy */
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
u16 * p_yuv = p_vout->chroma.p_sys->p_rgb16;
u16 * p_ybase; /* Y dependant conversion table */
#endif
/* Conversion buffer pointer */
u16 * p_buffer_start = (u16*)p_vout->chroma.p_sys->p_buffer;
u16 * p_buffer;
/* Offset array pointer */
int * p_offset_start = p_vout->chroma.p_sys->p_offset;
int * p_offset;
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
if( p_vout->render.i_width & 7 )
{
i_rewind = 8 - ( p_vout->render.i_width & 7 );
}
else
{
i_rewind = 0;
}
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_vout->render.i_width, p_vout->render.i_height,
p_vout->output.i_width, p_vout->output.i_height,
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_vout->output.i_height : p_vout->render.i_height;
for( i_y = 0; i_y < p_vout->render.i_height; i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_15
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
/* Here we do some unaligned reads and duplicate conversions, but
* at least we have all the pixels */
if( i_rewind )
{
p_y -= i_rewind;
p_u -= i_rewind >> 1;
p_v -= i_rewind >> 1;
p_buffer -= i_rewind;
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_15
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
SCALE_WIDTH;
SCALE_HEIGHT( 420, 2 );
}
}
/*****************************************************************************
* I420_RGB16: color YUV 4:2:0 to RGB 16 bpp
*****************************************************************************
* Horizontal alignment needed:
* - input: 8 pixels (8 Y bytes, 4 U/V bytes), margins not allowed
* - output: 1 pixel (2 bytes), margins allowed
* Vertical alignment needed:
* - input: 2 lines (2 Y lines, 1 U/V line)
* - output: 1 line
*****************************************************************************/
void E_(I420_RGB16)( vout_thread_t *p_vout, picture_t *p_src,
picture_t *p_dest )
{
/* We got this one from the old arguments */
u16 *p_pic = (u16*)p_dest->p->p_pixels;
u8 *p_y = p_src->Y_PIXELS;
u8 *p_u = p_src->U_PIXELS;
u8 *p_v = p_src->V_PIXELS;
vlc_bool_t b_hscale; /* horizontal scaling type */
int i_vscale; /* vertical scaling type */
int i_x, i_y; /* horizontal and vertical indexes */
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_vout->render.i_width / 2; /* chroma width */
u16 * p_pic_start; /* beginning of the current line for copy */
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
u16 * p_yuv = p_vout->chroma.p_sys->p_rgb16;
u16 * p_ybase; /* Y dependant conversion table */
#endif
/* Conversion buffer pointer */
u16 * p_buffer_start = (u16*)p_vout->chroma.p_sys->p_buffer;
u16 * p_buffer;
/* Offset array pointer */
int * p_offset_start = p_vout->chroma.p_sys->p_offset;
int * p_offset;
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
if( p_vout->render.i_width & 7 )
{
i_rewind = 8 - ( p_vout->render.i_width & 7 );
}
else
{
i_rewind = 0;
}
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_vout->render.i_width, p_vout->render.i_height,
p_vout->output.i_width, p_vout->output.i_height,
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_vout->output.i_height : p_vout->render.i_height;
for( i_y = 0; i_y < p_vout->render.i_height; i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
/* Here we do some unaligned reads and duplicate conversions, but
* at least we have all the pixels */
if( i_rewind )
{
p_y -= i_rewind;
p_u -= i_rewind >> 1;
p_v -= i_rewind >> 1;
p_buffer -= i_rewind;
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
SCALE_WIDTH;
SCALE_HEIGHT( 420, 2 );
}
}
/*****************************************************************************
* I420_RGB32: color YUV 4:2:0 to RGB 32 bpp
*****************************************************************************
* Horizontal alignment needed:
* - input: 8 pixels (8 Y bytes, 4 U/V bytes), margins not allowed
* - output: 1 pixel (2 bytes), margins allowed
* Vertical alignment needed:
* - input: 2 lines (2 Y lines, 1 U/V line)
* - output: 1 line
*****************************************************************************/
void E_(I420_RGB32)( vout_thread_t *p_vout, picture_t *p_src,
picture_t *p_dest )
{
/* We got this one from the old arguments */
u32 *p_pic = (u32*)p_dest->p->p_pixels;
u8 *p_y = p_src->Y_PIXELS;
u8 *p_u = p_src->U_PIXELS;
u8 *p_v = p_src->V_PIXELS;
vlc_bool_t b_hscale; /* horizontal scaling type */
int i_vscale; /* vertical scaling type */
int i_x, i_y; /* horizontal and vertical indexes */
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_vout->render.i_width / 4; /* chroma width */
u32 * p_pic_start; /* beginning of the current line for copy */
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
u32 * p_yuv = p_vout->chroma.p_sys->p_rgb32;
u32 * p_ybase; /* Y dependant conversion table */
#endif
/* Conversion buffer pointer */
u32 * p_buffer_start = (u32*)p_vout->chroma.p_sys->p_buffer;
u32 * p_buffer;
/* Offset array pointer */
int * p_offset_start = p_vout->chroma.p_sys->p_offset;
int * p_offset;
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
if( p_vout->render.i_width & 7 )
{
i_rewind = 8 - ( p_vout->render.i_width & 7 );
}
else
{
i_rewind = 0;
}
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_vout->render.i_width, p_vout->render.i_height,
p_vout->output.i_width, p_vout->output.i_height,
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_vout->output.i_height : p_vout->render.i_height;
for( i_y = 0; i_y < p_vout->render.i_height; i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
__asm__( MMX_INIT_32
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_32
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
/* Here we do some unaligned reads and duplicate conversions, but
* at least we have all the pixels */
if( i_rewind )
{
p_y -= i_rewind;
p_u -= i_rewind >> 1;
p_v -= i_rewind >> 1;
p_buffer -= i_rewind;
#if defined (MODULE_NAME_IS_chroma_i420_rgb)
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
#elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
__asm__( MMX_INIT_32
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_32
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
SCALE_WIDTH;
SCALE_HEIGHT( 420, 4 );
}
}
/* Following functions are local */
/*****************************************************************************
* SetOffset: build offset array for conversion functions
*****************************************************************************
* This function will build an offset array used in later conversion functions.
* It will also set horizontal and vertical scaling indicators.
*****************************************************************************/
static void SetOffset( int i_width, int i_height, int i_pic_width,
int i_pic_height, vlc_bool_t *pb_hscale,
int *pi_vscale, int *p_offset )
{
int i_x; /* x position in destination */
int i_scale_count; /* modulo counter */
/*
* Prepare horizontal offset array
*/
if( i_pic_width - i_width == 0 )
{
/* No horizontal scaling: YUV conversion is done directly to picture */
*pb_hscale = 0;
}
else if( i_pic_width - i_width > 0 )
{
/* Prepare scaling array for horizontal extension */
*pb_hscale = 1;
i_scale_count = i_pic_width;
for( i_x = i_width; i_x--; )
{
while( (i_scale_count -= i_width) > 0 )
{
*p_offset++ = 0;
}
*p_offset++ = 1;
i_scale_count += i_pic_width;
}
}
else /* if( i_pic_width - i_width < 0 ) */
{
/* Prepare scaling array for horizontal reduction */
*pb_hscale = 1;
i_scale_count = i_width;
for( i_x = i_pic_width; i_x--; )
{
*p_offset = 1;
while( (i_scale_count -= i_pic_width) > 0 )
{
*p_offset += 1;
}
p_offset++;
i_scale_count += i_width;
}
}
/*
* Set vertical scaling indicator
*/
if( i_pic_height - i_height == 0 )
{
*pi_vscale = 0;
}
else if( i_pic_height - i_height > 0 )
{
*pi_vscale = 1;
}
else /* if( i_pic_height - i_height < 0 ) */
{
*pi_vscale = -1;
}
}

View File

@ -1,177 +0,0 @@
/*****************************************************************************
* i420_rgb8.c : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: i420_rgb8.c,v 1.8 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "i420_rgb.h"
#include "i420_rgb_c.h"
static void SetOffset( int, int, int, int, vlc_bool_t *, int *, int * );
/*****************************************************************************
* I420_RGB8: color YUV 4:2:0 to RGB 8 bpp
*****************************************************************************/
void E_(I420_RGB8)( vout_thread_t *p_vout, picture_t *p_src, picture_t *p_dest )
{
/* We got this one from the old arguments */
u8 *p_pic = (u8*)p_dest->p->p_pixels;
u8 *p_y = p_src->Y_PIXELS;
u8 *p_u = p_src->U_PIXELS;
u8 *p_v = p_src->V_PIXELS;
vlc_bool_t b_hscale; /* horizontal scaling type */
int i_vscale; /* vertical scaling type */
int i_x, i_y; /* horizontal and vertical indexes */
int i_real_y; /* y % 4 */
int i_right_margin;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_vout->render.i_width / 2; /* chroma width */
/* Lookup table */
u8 * p_lookup = p_vout->chroma.p_sys->p_base;
/* Offset array pointer */
int * p_offset_start = p_vout->chroma.p_sys->p_offset;
int * p_offset;
/* The dithering matrices */
static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
SetOffset( p_vout->render.i_width, p_vout->render.i_height,
p_vout->output.i_width, p_vout->output.i_height,
&b_hscale, &i_vscale, p_offset_start );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_vout->output.i_height : p_vout->render.i_height;
for( i_y = 0, i_real_y = 0; i_y < p_vout->render.i_height; i_y++ )
{
/* Do horizontal and vertical scaling */
SCALE_WIDTH_DITHER( 420 );
SCALE_HEIGHT_DITHER( 420 );
}
}
/* Following functions are local */
/*****************************************************************************
* SetOffset: build offset array for conversion functions
*****************************************************************************
* This function will build an offset array used in later conversion functions.
* It will also set horizontal and vertical scaling indicators. The p_offset
* structure has interleaved Y and U/V offsets.
*****************************************************************************/
static void SetOffset( int i_width, int i_height, int i_pic_width,
int i_pic_height, vlc_bool_t *pb_hscale,
int *pi_vscale, int *p_offset )
{
int i_x; /* x position in destination */
int i_scale_count; /* modulo counter */
/*
* Prepare horizontal offset array
*/
if( i_pic_width - i_width == 0 )
{
/* No horizontal scaling: YUV conversion is done directly to picture */
*pb_hscale = 0;
}
else if( i_pic_width - i_width > 0 )
{
int i_dummy = 0;
/* Prepare scaling array for horizontal extension */
*pb_hscale = 1;
i_scale_count = i_pic_width;
for( i_x = i_width; i_x--; )
{
while( (i_scale_count -= i_width) > 0 )
{
*p_offset++ = 0;
*p_offset++ = 0;
}
*p_offset++ = 1;
*p_offset++ = i_dummy;
i_dummy = 1 - i_dummy;
i_scale_count += i_pic_width;
}
}
else /* if( i_pic_width - i_width < 0 ) */
{
int i_remainder = 0;
int i_jump;
/* Prepare scaling array for horizontal reduction */
*pb_hscale = 1;
i_scale_count = i_width;
for( i_x = i_pic_width; i_x--; )
{
i_jump = 1;
while( (i_scale_count -= i_pic_width) > 0 )
{
i_jump += 1;
}
*p_offset++ = i_jump;
*p_offset++ = ( i_jump += i_remainder ) >> 1;
i_remainder = i_jump & 1;
i_scale_count += i_width;
}
}
/*
* Set vertical scaling indicator
*/
if( i_pic_height - i_height == 0 )
{
*pi_vscale = 0;
}
else if( i_pic_height - i_height > 0 )
{
*pi_vscale = 1;
}
else /* if( i_pic_height - i_height < 0 ) */
{
*pi_vscale = -1;
}
}

View File

@ -1,55 +0,0 @@
/*****************************************************************************
* chroma_common.h: YUV transformation functions
* Provides functions to perform the YUV conversion. The functions provided here
* are a complete and portable C implementation, and may be replaced in certain
* case by optimized functions.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: i420_rgb_c.h,v 1.1 2002/01/04 14:01:34 sam Exp $
*
* Authors: Vincent Seguin <seguin@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-1307, USA.
*****************************************************************************/
/*****************************************************************************
* Constants
*****************************************************************************/
/* Margins and offsets in conversion tables - Margins are used in case a RGB
* RGB conversion would give a value outside the 0-255 range. Offsets have been
* calculated to avoid using the same cache line for 2 tables. conversion tables
* are 2*MARGIN + 256 long and stores pixels.*/
#define RED_MARGIN 178
#define GREEN_MARGIN 135
#define BLUE_MARGIN 224
#define RED_OFFSET 1501 /* 1323 to 1935 */
#define GREEN_OFFSET 135 /* 0 to 526 */
#define BLUE_OFFSET 818 /* 594 to 1298 */
#define RGB_TABLE_SIZE 1935 /* total table size */
#define GRAY_MARGIN 384
#define GRAY_TABLE_SIZE 1024 /* total table size */
#define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table */
/* macros used for YUV pixel conversions */
#define SHIFT 20
#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))

View File

@ -1,284 +0,0 @@
/*****************************************************************************
* transforms_yuvmmx.h: MMX YUV transformation assembly
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: i420_rgb_mmx.h,v 1.3 2002/06/01 12:31:58 sam Exp $
*
* Authors: Olie Lho <ollie@sis.com.tw>
* Gaël Hendryckx <jimmy@via.ecp.fr>
* Samuel Hocevar <sam@zoy.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-1307, USA.
*****************************************************************************/
/* hope these constant values are cache line aligned */
#define UNUSED_LONGLONG(foo) \
static const unsigned long long foo __asm__ (#foo) __attribute__((unused))
UNUSED_LONGLONG(mmx_80w) = 0x0080008000800080;
UNUSED_LONGLONG(mmx_10w) = 0x1010101010101010;
UNUSED_LONGLONG(mmx_00ffw) = 0x00ff00ff00ff00ff;
UNUSED_LONGLONG(mmx_Y_coeff) = 0x253f253f253f253f;
UNUSED_LONGLONG(mmx_U_green) = 0xf37df37df37df37d;
UNUSED_LONGLONG(mmx_U_blue) = 0x4093409340934093;
UNUSED_LONGLONG(mmx_V_red) = 0x3312331233123312;
UNUSED_LONGLONG(mmx_V_green) = 0xe5fce5fce5fce5fc;
UNUSED_LONGLONG(mmx_mask_f8) = 0xf8f8f8f8f8f8f8f8;
UNUSED_LONGLONG(mmx_mask_fc) = 0xfcfcfcfcfcfcfcfc;
#undef UNUSED_LONGLONG
#define MMX_INIT_16 " \n\
movd (%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
pxor %%mm4, %%mm4 # zero mm4 \n\
movq (%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
#movl $0, (%3) # cache preload for image \n\
"
#define MMX_INIT_16_GRAY " \n\
movq (%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
#movl $0, (%3) # cache preload for image \n\
"
#define MMX_INIT_32 " \n\
movd (%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movl $0, (%3) # cache preload for image \n\
movd (%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
pxor %%mm4, %%mm4 # zero mm4 \n\
movq (%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
"
/*
* Do the multiply part of the conversion for even and odd pixels,
* register usage:
* mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels,
* mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels,
* mm6 -> Y even, mm7 -> Y odd
*/
#define MMX_YUV_MUL " \n\
# convert the chroma part \n\
punpcklbw %%mm4, %%mm0 # scatter 4 Cb 00 u3 00 u2 00 u1 00 u0 \n\
punpcklbw %%mm4, %%mm1 # scatter 4 Cr 00 v3 00 v2 00 v1 00 v0 \n\
psubsw mmx_80w, %%mm0 # Cb -= 128 \n\
psubsw mmx_80w, %%mm1 # Cr -= 128 \n\
psllw $3, %%mm0 # Promote precision \n\
psllw $3, %%mm1 # Promote precision \n\
movq %%mm0, %%mm2 # Copy 4 Cb 00 u3 00 u2 00 u1 00 u0 \n\
movq %%mm1, %%mm3 # Copy 4 Cr 00 v3 00 v2 00 v1 00 v0 \n\
pmulhw mmx_U_green, %%mm2 # Mul Cb with green coeff -> Cb green \n\
pmulhw mmx_V_green, %%mm3 # Mul Cr with green coeff -> Cr green \n\
pmulhw mmx_U_blue, %%mm0 # Mul Cb -> Cblue 00 b3 00 b2 00 b1 00 b0 \n\
pmulhw mmx_V_red, %%mm1 # Mul Cr -> Cred 00 r3 00 r2 00 r1 00 r0 \n\
paddsw %%mm3, %%mm2 # Cb green + Cr green -> Cgreen \n\
\n\
# convert the luma part \n\
psubusb mmx_10w, %%mm6 # Y -= 16 \n\
movq %%mm6, %%mm7 # Copy 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
pand mmx_00ffw, %%mm6 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0 \n\
psrlw $8, %%mm7 # get Y odd 00 Y7 00 Y5 00 Y3 00 Y1 \n\
psllw $3, %%mm6 # Promote precision \n\
psllw $3, %%mm7 # Promote precision \n\
pmulhw mmx_Y_coeff, %%mm6 # Mul 4 Y even 00 y6 00 y4 00 y2 00 y0 \n\
pmulhw mmx_Y_coeff, %%mm7 # Mul 4 Y odd 00 y7 00 y5 00 y3 00 y1 \n\
"
/*
* Do the addition part of the conversion for even and odd pixels,
* register usage:
* mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels,
* mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels,
* mm6 -> Y even, mm7 -> Y odd
*/
#define MMX_YUV_ADD " \n\
# Do horizontal and vertical scaling \n\
movq %%mm0, %%mm3 # Copy Cblue \n\
movq %%mm1, %%mm4 # Copy Cred \n\
movq %%mm2, %%mm5 # Copy Cgreen \n\
paddsw %%mm6, %%mm0 # Y even + Cblue 00 B6 00 B4 00 B2 00 B0 \n\
paddsw %%mm7, %%mm3 # Y odd + Cblue 00 B7 00 B5 00 B3 00 B1 \n\
paddsw %%mm6, %%mm1 # Y even + Cred 00 R6 00 R4 00 R2 00 R0 \n\
paddsw %%mm7, %%mm4 # Y odd + Cred 00 R7 00 R5 00 R3 00 R1 \n\
paddsw %%mm6, %%mm2 # Y even + Cgreen 00 G6 00 G4 00 G2 00 G0 \n\
paddsw %%mm7, %%mm5 # Y odd + Cgreen 00 G7 00 G5 00 G3 00 G1 \n\
\n\
# Limit RGB even to 0..255 \n\
packuswb %%mm0, %%mm0 # B6 B4 B2 B0 / B6 B4 B2 B0 \n\
packuswb %%mm1, %%mm1 # R6 R4 R2 R0 / R6 R4 R2 R0 \n\
packuswb %%mm2, %%mm2 # G6 G4 G2 G0 / G6 G4 G2 G0 \n\
\n\
# Limit RGB odd to 0..255 \n\
packuswb %%mm3, %%mm3 # B7 B5 B3 B1 / B7 B5 B3 B1 \n\
packuswb %%mm4, %%mm4 # R7 R5 R3 R1 / R7 R5 R3 R1 \n\
packuswb %%mm5, %%mm5 # G7 G5 G3 G1 / G7 G5 G3 G1 \n\
\n\
# Interleave RGB even and odd \n\
punpcklbw %%mm3, %%mm0 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
punpcklbw %%mm4, %%mm1 # R7 R6 R5 R4 R3 R2 R1 R0 \n\
punpcklbw %%mm5, %%mm2 # G7 G6 G5 G4 G3 G2 G1 G0 \n\
"
/*
* Grayscale case, only use Y
*/
#define MMX_YUV_GRAY " \n\
# convert the luma part \n\
psubusb mmx_10w, %%mm6 \n\
movq %%mm6, %%mm7 \n\
pand mmx_00ffw, %%mm6 \n\
psrlw $8, %%mm7 \n\
psllw $3, %%mm6 \n\
psllw $3, %%mm7 \n\
pmulhw mmx_Y_coeff, %%mm6 \n\
pmulhw mmx_Y_coeff, %%mm7 \n\
packuswb %%mm6, %%mm6 \n\
packuswb %%mm7, %%mm7 \n\
punpcklbw %%mm7, %%mm6 \n\
"
#define MMX_UNPACK_16_GRAY " \n\
movq %%mm6, %%mm5 \n\
pand mmx_mask_f8, %%mm6 \n\
pand mmx_mask_fc, %%mm5 \n\
movq %%mm6, %%mm7 \n\
psrlw $3, %%mm7 \n\
pxor %%mm3, %%mm3 \n\
movq %%mm7, %%mm2 \n\
movq %%mm5, %%mm0 \n\
punpcklbw %%mm3, %%mm5 \n\
punpcklbw %%mm6, %%mm7 \n\
psllw $3, %%mm5 \n\
por %%mm5, %%mm7 \n\
movq %%mm7, (%3) \n\
punpckhbw %%mm3, %%mm0 \n\
punpckhbw %%mm6, %%mm2 \n\
psllw $3, %%mm0 \n\
movq 8(%0), %%mm6 \n\
por %%mm0, %%mm2 \n\
movq %%mm2, 8(%3) \n\
"
/*
* convert RGB plane to RGB 15 bits,
* mm0 -> B, mm1 -> R, mm2 -> G,
* mm4 -> GB, mm5 -> AR pixel 4-7,
* mm6 -> GB, mm7 -> AR pixel 0-3
*/
#define MMX_UNPACK_15 " \n\
# mask unneeded bits off \n\
pand mmx_mask_f8, %%mm0 # b7b6b5b4 b3______ b7b6b5b4 b3______ \n\
psrlw $3,%%mm0 # ______b7 b6b5b4b3 ______b7 b6b5b4b3 \n\
pand mmx_mask_f8, %%mm2 # g7g6g5g4 g3______ g7g6g5g4 g3______ \n\
pand mmx_mask_f8, %%mm1 # r7r6r5r4 r3______ r7r6r5r4 r3______ \n\
psrlw $1,%%mm1 # __r7r6r5 r4r3____ __r7r6r5 r4r3____ \n\
pxor %%mm4, %%mm4 # zero mm4 \n\
movq %%mm0, %%mm5 # Copy B7-B0 \n\
movq %%mm2, %%mm7 # Copy G7-G0 \n\
\n\
# convert rgb24 plane to rgb15 pack for pixel 0-3 \n\
punpcklbw %%mm4, %%mm2 # ________ ________ g7g6g5g4 g3______ \n\
punpcklbw %%mm1, %%mm0 # r7r6r5r4 r3______ ______b7 b6b5b4b3 \n\
psllw $2,%%mm2 # ________ ____g7g6 g5g4g3__ ________ \n\
por %%mm2, %%mm0 # r7r6r5r4 r3__g7g6 g5g4g3b7 b6b5b4b3 \n\
movq 8(%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movq %%mm0, (%3) # store pixel 0-3 \n\
\n\
# convert rgb24 plane to rgb16 pack for pixel 0-3 \n\
punpckhbw %%mm4, %%mm7 # ________ ________ g7g6g5g4 g3______ \n\
punpckhbw %%mm1, %%mm5 # r7r6r5r4 r3______ ______b7 b6b5b4b3 \n\
psllw $2,%%mm7 # ________ ____g7g6 g5g4g3__ ________ \n\
movd 4(%1), %%mm0 # Load 4 Cb __ __ __ __ u3 u2 u1 u0 \n\
por %%mm7, %%mm5 # r7r6r5r4 r3__g7g6 g5g4g3b7 b6b5b4b3 \n\
movd 4(%2), %%mm1 # Load 4 Cr __ __ __ __ v3 v2 v1 v0 \n\
movq %%mm5, 8(%3) # store pixel 4-7 \n\
"
/*
* convert RGB plane to RGB 16 bits,
* mm0 -> B, mm1 -> R, mm2 -> G,
* mm4 -> GB, mm5 -> AR pixel 4-7,
* mm6 -> GB, mm7 -> AR pixel 0-3
*/
#define MMX_UNPACK_16 " \n\
# mask unneeded bits off \n\
pand mmx_mask_f8, %%mm0 # b7b6b5b4 b3______ b7b6b5b4 b3______ \n\
pand mmx_mask_fc, %%mm2 # g7g6g5g4 g3g2____ g7g6g5g4 g3g2____ \n\
pand mmx_mask_f8, %%mm1 # r7r6r5r4 r3______ r7r6r5r4 r3______ \n\
psrlw $3,%%mm0 # ______b7 b6b5b4b3 ______b7 b6b5b4b3 \n\
pxor %%mm4, %%mm4 # zero mm4 \n\
movq %%mm0, %%mm5 # Copy B7-B0 \n\
movq %%mm2, %%mm7 # Copy G7-G0 \n\
\n\
# convert rgb24 plane to rgb16 pack for pixel 0-3 \n\
punpcklbw %%mm4, %%mm2 # ________ ________ g7g6g5g4 g3g2____ \n\
punpcklbw %%mm1, %%mm0 # r7r6r5r4 r3______ ______b7 b6b5b4b3 \n\
psllw $3,%%mm2 # ________ __g7g6g5 g4g3g2__ ________ \n\
por %%mm2, %%mm0 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3 \n\
movq 8(%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movq %%mm0, (%3) # store pixel 0-3 \n\
\n\
# convert rgb24 plane to rgb16 pack for pixel 0-3 \n\
punpckhbw %%mm4, %%mm7 # ________ ________ g7g6g5g4 g3g2____ \n\
punpckhbw %%mm1, %%mm5 # r7r6r5r4 r3______ ______b7 b6b5b4b3 \n\
psllw $3,%%mm7 # ________ __g7g6g5 g4g3g2__ ________ \n\
movd 4(%1), %%mm0 # Load 4 Cb __ __ __ __ u3 u2 u1 u0 \n\
por %%mm7, %%mm5 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3 \n\
movd 4(%2), %%mm1 # Load 4 Cr __ __ __ __ v3 v2 v1 v0 \n\
movq %%mm5, 8(%3) # store pixel 4-7 \n\
"
/*
* convert RGB plane to RGB packed format,
* mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0,
* mm4 -> GB, mm5 -> AR pixel 4-7,
* mm6 -> GB, mm7 -> AR pixel 0-3
*/
#define MMX_UNPACK_32 " \n\
pxor %%mm3, %%mm3 # zero mm3 \n\
movq %%mm0, %%mm6 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
movq %%mm1, %%mm7 # R7 R6 R5 R4 R3 R2 R1 R0 \n\
movq %%mm0, %%mm4 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
movq %%mm1, %%mm5 # R7 R6 R5 R4 R3 R2 R1 R0 \n\
punpcklbw %%mm2, %%mm6 # G3 B3 G2 B2 G1 B1 G0 B0 \n\
punpcklbw %%mm3, %%mm7 # 00 R3 00 R2 00 R1 00 R0 \n\
punpcklwd %%mm7, %%mm6 # 00 R1 B1 G1 00 R0 B0 G0 \n\
movq %%mm6, (%3) # Store ARGB1 ARGB0 \n\
movq %%mm0, %%mm6 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
punpcklbw %%mm2, %%mm6 # G3 B3 G2 B2 G1 B1 G0 B0 \n\
punpckhwd %%mm7, %%mm6 # 00 R3 G3 B3 00 R2 B3 G2 \n\
movq %%mm6, 8(%3) # Store ARGB3 ARGB2 \n\
punpckhbw %%mm2, %%mm4 # G7 B7 G6 B6 G5 B5 G4 B4 \n\
punpckhbw %%mm3, %%mm5 # 00 R7 00 R6 00 R5 00 R4 \n\
punpcklwd %%mm5, %%mm4 # 00 R5 B5 G5 00 R4 B4 G4 \n\
movq %%mm4, 16(%3) # Store ARGB5 ARGB4 \n\
movq %%mm0, %%mm4 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
punpckhbw %%mm2, %%mm4 # G7 B7 G6 B6 G5 B5 G4 B4 \n\
punpckhwd %%mm5, %%mm4 # 00 R7 G7 B7 00 R6 B6 G6 \n\
movq %%mm4, 24(%3) # Store ARGB7 ARGB6 \n\
\n\
#movd 4(%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
#movd 4(%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
#pxor %%mm4, %%mm4 # zero mm4 \n\
#movq 8(%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
"

View File

@ -1,150 +0,0 @@
/*****************************************************************************
* i420_ymga.c : YUV to YUV conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_ymga.c,v 1.8 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#define SRC_FOURCC "I420,IYUV,YV12"
#define DEST_FOURCC "YMGA"
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Activate ( vlc_object_t * );
static void I420_YMGA ( vout_thread_t *, picture_t *, picture_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
#if defined (MODULE_NAME_IS_chroma_i420_ymga)
set_description( _("conversions from " SRC_FOURCC " to " DEST_FOURCC) );
set_capability( "chroma", 80 );
#elif defined (MODULE_NAME_IS_chroma_i420_ymga_mmx)
set_description( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) );
set_capability( "chroma", 100 );
add_requirement( MMX );
#endif
set_callbacks( Activate, NULL );
vlc_module_end();
/*****************************************************************************
* Activate: allocate a chroma function
*****************************************************************************
* This function allocates and initializes a chroma function
*****************************************************************************/
static int Activate( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
{
return -1;
}
switch( p_vout->render.i_chroma )
{
case VLC_FOURCC('Y','V','1','2'):
case VLC_FOURCC('I','4','2','0'):
case VLC_FOURCC('I','Y','U','V'):
switch( p_vout->output.i_chroma )
{
case VLC_FOURCC('Y','M','G','A'):
p_vout->chroma.pf_convert = I420_YMGA;
break;
default:
return -1;
}
break;
default:
return -1;
}
return 0;
}
/* Following functions are local */
/*****************************************************************************
* I420_YMGA: planar YUV 4:2:0 to Matrox's planar/packed YUV 4:2:0
*****************************************************************************/
static void I420_YMGA( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_uv = p_dest->U_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x;
/* Copy the Y part */
p_vout->p_vlc->pf_memcpy( p_dest->Y_PIXELS, p_source->Y_PIXELS,
p_dest->p[Y_PLANE].i_pitch * p_dest->p[Y_PLANE].i_lines );
/* Copy the U:V part */
for( i_x = p_dest->p[U_PLANE].i_pitch * p_dest->p[U_PLANE].i_lines / 64;
i_x--; )
{
#if defined (MODULE_NAME_IS_chroma_i420_ymga)
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
*p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
#else
__asm__( ".align 32 \n\
movd (%0), %%mm0 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
movd 4(%0), %%mm2 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
movd 8(%0), %%mm4 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
movd 12(%0), %%mm6 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
movd (%1), %%mm1 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd 4(%1), %%mm3 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd 8(%1), %%mm5 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd 12(%1), %%mm7 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
punpcklbw %%mm1, %%mm0 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm3, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm5, %%mm4 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm7, %%mm6 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm0, (%2) # Store CrCb \n\
movq %%mm2, 8(%2) # Store CrCb \n\
movq %%mm4, 16(%2) # Store CrCb \n\
movq %%mm6, 24(%2) # Store CrCb"
: : "r" (p_v), "r" (p_u), "r" (p_uv) );
p_v += 16; p_u += 16; p_uv += 32;
#endif
}
}

View File

@ -1,377 +0,0 @@
/*****************************************************************************
* i420_yuy2.c : YUV to YUV conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_yuy2.c,v 1.11 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "i420_yuy2.h"
#define SRC_FOURCC "I420,IYUV,YV12"
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
# define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv,Y211"
#else
# define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv"
#endif
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Activate ( vlc_object_t * );
static void I420_YUY2 ( vout_thread_t *, picture_t *, picture_t * );
static void I420_YVYU ( vout_thread_t *, picture_t *, picture_t * );
static void I420_UYVY ( vout_thread_t *, picture_t *, picture_t * );
static void I420_IUYV ( vout_thread_t *, picture_t *, picture_t * );
static void I420_cyuv ( vout_thread_t *, picture_t *, picture_t * );
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
static void I420_Y211 ( vout_thread_t *, picture_t *, picture_t * );
#endif
#ifdef MODULE_NAME_IS_chroma_i420_yuy2_mmx
static unsigned long long i_00ffw;
static unsigned long long i_80w;
#endif
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
vlc_module_begin();
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
set_description( _("conversions from " SRC_FOURCC " to " DEST_FOURCC) );
set_capability( "chroma", 80 );
#elif defined (MODULE_NAME_IS_chroma_i420_yuy2_mmx)
set_description( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) );
set_capability( "chroma", 100 );
add_requirement( MMX );
/* Initialize MMX-specific constants */
i_00ffw = 0x00ff00ff00ff00ff;
i_80w = 0x0000000080808080;
#endif
set_callbacks( Activate, NULL );
vlc_module_end();
/*****************************************************************************
* Activate: allocate a chroma function
*****************************************************************************
* This function allocates and initializes a chroma function
*****************************************************************************/
static int Activate( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
{
return -1;
}
switch( p_vout->render.i_chroma )
{
case VLC_FOURCC('Y','V','1','2'):
case VLC_FOURCC('I','4','2','0'):
case VLC_FOURCC('I','Y','U','V'):
switch( p_vout->output.i_chroma )
{
case VLC_FOURCC('Y','U','Y','2'):
case VLC_FOURCC('Y','U','N','V'):
p_vout->chroma.pf_convert = I420_YUY2;
break;
case VLC_FOURCC('Y','V','Y','U'):
p_vout->chroma.pf_convert = I420_YVYU;
break;
case VLC_FOURCC('U','Y','V','Y'):
case VLC_FOURCC('U','Y','N','V'):
case VLC_FOURCC('Y','4','2','2'):
p_vout->chroma.pf_convert = I420_UYVY;
break;
case VLC_FOURCC('I','U','Y','V'):
p_vout->chroma.pf_convert = I420_IUYV;
break;
case VLC_FOURCC('c','y','u','v'):
p_vout->chroma.pf_convert = I420_cyuv;
break;
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
case VLC_FOURCC('Y','2','1','1'):
p_vout->chroma.pf_convert = I420_Y211;
break;
#endif
default:
return -1;
}
break;
default:
return -1;
}
return 0;
}
/* Following functions are local */
/*****************************************************************************
* I420_YUY2: planar YUV 4:2:0 to packed YUYV 4:2:2
*****************************************************************************/
static void I420_YUY2( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line1, *p_line2 = p_dest->p->p_pixels;
u8 *p_y1, *p_y2 = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
const int i_source_margin = p_source->p->i_pitch
- p_source->p->i_visible_pitch;
const int i_dest_margin = p_dest->p->i_pitch
- p_dest->p->i_visible_pitch;
for( i_y = p_vout->render.i_height / 2 ; i_y-- ; )
{
p_line1 = p_line2;
p_line2 += p_dest->p->i_pitch;
p_y1 = p_y2;
p_y2 += p_source->p[Y_PLANE].i_pitch;
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_YUYV( );
C_YUV420_YUYV( );
C_YUV420_YUYV( );
C_YUV420_YUYV( );
#else
MMX_CALL( MMX_YUV420_YUYV );
#endif
}
p_y1 += i_source_margin;
p_y2 += i_source_margin;
p_line1 += i_dest_margin;
p_line2 += i_dest_margin;
}
}
/*****************************************************************************
* I420_YVYU: planar YUV 4:2:0 to packed YVYU 4:2:2
*****************************************************************************/
static void I420_YVYU( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line1, *p_line2 = p_dest->p->p_pixels;
u8 *p_y1, *p_y2 = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
const int i_source_margin = p_source->p->i_pitch
- p_source->p->i_visible_pitch;
const int i_dest_margin = p_dest->p->i_pitch
- p_dest->p->i_visible_pitch;
for( i_y = p_vout->render.i_height / 2 ; i_y-- ; )
{
p_line1 = p_line2;
p_line2 += p_dest->p->i_pitch;
p_y1 = p_y2;
p_y2 += p_source->p[Y_PLANE].i_pitch;
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_YVYU( );
C_YUV420_YVYU( );
C_YUV420_YVYU( );
C_YUV420_YVYU( );
#else
MMX_CALL( MMX_YUV420_YVYU );
#endif
}
p_y1 += i_source_margin;
p_y2 += i_source_margin;
p_line1 += i_dest_margin;
p_line2 += i_dest_margin;
}
}
/*****************************************************************************
* I420_UYVY: planar YUV 4:2:0 to packed UYVY 4:2:2
*****************************************************************************/
static void I420_UYVY( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line1, *p_line2 = p_dest->p->p_pixels;
u8 *p_y1, *p_y2 = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
const int i_source_margin = p_source->p->i_pitch
- p_source->p->i_visible_pitch;
const int i_dest_margin = p_dest->p->i_pitch
- p_dest->p->i_visible_pitch;
for( i_y = p_vout->render.i_height / 2 ; i_y-- ; )
{
p_line1 = p_line2;
p_line2 += p_dest->p->i_pitch;
p_y1 = p_y2;
p_y2 += p_source->p[Y_PLANE].i_pitch;
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_UYVY( );
C_YUV420_UYVY( );
C_YUV420_UYVY( );
C_YUV420_UYVY( );
#else
MMX_CALL( MMX_YUV420_UYVY );
#endif
}
p_y1 += i_source_margin;
p_y2 += i_source_margin;
p_line1 += i_dest_margin;
p_line2 += i_dest_margin;
}
}
/*****************************************************************************
* I420_IUYV: planar YUV 4:2:0 to interleaved packed UYVY 4:2:2
*****************************************************************************/
static void I420_IUYV( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
/* FIXME: TODO ! */
msg_Err( p_vout, "I420_IUYV unimplemented, please harass <sam@zoy.org>" );
}
/*****************************************************************************
* I420_cyuv: planar YUV 4:2:0 to upside-down packed UYVY 4:2:2
*****************************************************************************/
static void I420_cyuv( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line1 = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch
+ p_dest->p->i_pitch;
u8 *p_line2 = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
u8 *p_y1, *p_y2 = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
const int i_source_margin = p_source->p->i_pitch
- p_source->p->i_visible_pitch;
const int i_dest_margin = p_dest->p->i_pitch
- p_dest->p->i_visible_pitch;
for( i_y = p_vout->render.i_height / 2 ; i_y-- ; )
{
p_line1 -= 3 * p_dest->p->i_pitch;
p_line2 -= 3 * p_dest->p->i_pitch;
p_y1 = p_y2;
p_y2 += p_source->p[Y_PLANE].i_pitch;
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_UYVY( );
C_YUV420_UYVY( );
C_YUV420_UYVY( );
C_YUV420_UYVY( );
#else
MMX_CALL( MMX_YUV420_UYVY );
#endif
}
p_y1 += i_source_margin;
p_y2 += i_source_margin;
p_line1 += i_dest_margin;
p_line2 += i_dest_margin;
}
}
/*****************************************************************************
* I420_Y211: planar YUV 4:2:0 to packed YUYV 2:1:1
*****************************************************************************/
#if defined (MODULE_NAME_IS_chroma_i420_yuy2)
static void I420_Y211( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line1, *p_line2 = p_dest->p->p_pixels;
u8 *p_y1, *p_y2 = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
const int i_source_margin = p_source->p->i_pitch
- p_source->p->i_visible_pitch;
const int i_dest_margin = p_dest->p->i_pitch
- p_dest->p->i_visible_pitch;
for( i_y = p_vout->render.i_height / 2 ; i_y-- ; )
{
p_line1 = p_line2;
p_line2 += p_dest->p->i_pitch;
p_y1 = p_y2;
p_y2 += p_source->p[Y_PLANE].i_pitch;
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
C_YUV420_Y211( );
C_YUV420_Y211( );
}
p_y1 += i_source_margin;
p_y2 += i_source_margin;
p_line1 += i_dest_margin;
p_line2 += i_dest_margin;
}
}
#endif

View File

@ -1,143 +0,0 @@
/*****************************************************************************
* i420_yuy2.h : YUV to YUV conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_yuy2.h,v 1.10 2002/06/01 16:45:34 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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.
*****************************************************************************/
#ifdef MODULE_NAME_IS_chroma_i420_yuy2_mmx
#define MMX_CALL(MMX_INSTRUCTIONS) \
do { \
__asm__ __volatile__( \
".align 8 \n\t" \
MMX_INSTRUCTIONS \
: \
: "r" (p_line1), "r" (p_line2), "r" (p_y1), "r" (p_y2), \
"r" (p_u), "r" (p_v) ); \
p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \
} while(0); \
#define MMX_YUV420_YUYV " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%4), %%mm1 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm2 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # v3 u3 v2 u2 v1 u1 v0 u0 \n\
movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\
punpcklbw %%mm1, %%mm2 # v1 y3 u1 y2 v0 y1 u0 y0 \n\
movq %%mm2, (%0) # Store low YUYV \n\
punpckhbw %%mm1, %%mm0 # v3 y7 u3 y6 v2 y5 u2 y4 \n\
movq %%mm0, 8(%0) # Store high YUYV \n\
movq (%3), %%mm0 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movq %%mm0, %%mm2 # Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
punpcklbw %%mm1, %%mm2 # v1 Y3 u1 Y2 v0 Y1 u0 Y0 \n\
movq %%mm2, (%1) # Store low YUYV \n\
punpckhbw %%mm1, %%mm0 # v3 Y7 u3 Y6 v2 Y5 u2 Y4 \n\
movq %%mm0, 8(%1) # Store high YUYV \n\
"
#define MMX_YUV420_YVYU " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%4), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\
punpcklbw %%mm1, %%mm2 # u1 y3 v1 y2 u0 y1 v0 y0 \n\
movq %%mm2, (%0) # Store low YUYV \n\
punpckhbw %%mm1, %%mm0 # u3 y7 v3 y6 u2 y5 v2 y4 \n\
movq %%mm0, 8(%0) # Store high YUYV \n\
movq (%3), %%mm0 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movq %%mm0, %%mm2 # Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
punpcklbw %%mm1, %%mm2 # u1 Y3 v1 Y2 u0 Y1 v0 Y0 \n\
movq %%mm2, (%1) # Store low YUYV \n\
punpckhbw %%mm1, %%mm0 # u3 Y7 v3 Y6 u2 Y5 v2 Y4 \n\
movq %%mm0, 8(%1) # Store high YUYV \n\
"
#define MMX_YUV420_UYVY " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movq (%3), %%mm3 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movd (%4), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm1, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm0, %%mm2 # y3 v1 y2 u1 y1 v0 y0 u0 \n\
movq %%mm2, (%0) # Store low UYVY \n\
movq %%mm1, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpckhbw %%mm0, %%mm2 # y3 v1 y2 u1 y1 v0 y0 u0 \n\
movq %%mm2, 8(%0) # Store high UYVY \n\
movq %%mm1, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm3, %%mm2 # Y3 v1 Y2 u1 Y1 v0 Y0 u0 \n\
movq %%mm2, (%1) # Store low UYVY \n\
punpckhbw %%mm3, %%mm1 # Y7 v3 Y6 u3 Y5 v2 Y4 u2 \n\
movq %%mm1, 8(%1) # Store high UYVY \n\
"
/* FIXME: this code does not work ! Chroma seems to be wrong. */
#define MMX_YUV420_Y211 " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movq (%3), %%mm1 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movd (%4), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm3 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
pand i_00ffw, %%mm0 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0 \n\
packuswb %%mm0, %%mm0 # pack Y y6 y4 y2 y0 y6 y4 y2 y0 \n\
pand i_00ffw, %%mm2 # get U even 00 u6 00 u4 00 u2 00 u0 \n\
packuswb %%mm2, %%mm2 # pack U 00 00 u2 u0 00 00 u2 u0 \n\
pand i_00ffw, %%mm3 # get V even 00 v6 00 v4 00 v2 00 v0 \n\
packuswb %%mm3, %%mm3 # pack V 00 00 v2 v0 00 00 v2 v0 \n\
punpcklbw %%mm3, %%mm2 # 00 00 00 00 v2 u2 v0 u0 \n\
psubsw i_80w, %%mm2 # U,V -= 128 \n\
punpcklbw %%mm2, %%mm0 # v2 y6 u2 y4 v0 y2 u0 y0 \n\
movq %%mm0, (%0) # Store YUYV \n\
pand i_00ffw, %%mm1 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0 \n\
packuswb %%mm1, %%mm1 # pack Y Y6 Y4 Y2 Y0 Y6 Y4 Y2 Y0 \n\
punpcklbw %%mm2, %%mm1 # v2 Y6 u2 Y4 v0 Y2 u0 Y0 \n\
movq %%mm1, (%1) # Store YUYV \n\
"
#else
#define C_YUV420_YUYV( ) \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_u)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v)++; \
#define C_YUV420_YVYU( ) \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_u)++; \
#define C_YUV420_UYVY( ) \
*(p_line1)++ = *(p_line2)++ = *(p_u)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
#define C_YUV420_Y211( ) \
*(p_line1)++ = *(p_y1); ((u16*)p_y1)++; \
*(p_line2)++ = *(p_y2); ((u16*)p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_u) - 0x80; ((u16*)p_u)++; \
*(p_line1)++ = *(p_y1); ((u16*)p_y1)++; \
*(p_line2)++ = *(p_y2); ((u16*)p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v) - 0x80; ((u16*)p_v)++; \
#endif

View File

@ -1,318 +0,0 @@
/*****************************************************************************
* i422_yuy2.c : YUV to YUV conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i422_yuy2.c,v 1.8 2002/07/31 20:56:51 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "i422_yuy2.h"
#define SRC_FOURCC "I422"
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
# define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv,Y211"
#else
# define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv"
#endif
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Activate ( vlc_object_t * );
static void I422_YUY2 ( vout_thread_t *, picture_t *, picture_t * );
static void I422_YVYU ( vout_thread_t *, picture_t *, picture_t * );
static void I422_UYVY ( vout_thread_t *, picture_t *, picture_t * );
static void I422_IUYV ( vout_thread_t *, picture_t *, picture_t * );
static void I422_cyuv ( vout_thread_t *, picture_t *, picture_t * );
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
static void I422_Y211 ( vout_thread_t *, picture_t *, picture_t * );
#endif
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
set_description( _("conversions from " SRC_FOURCC " to " DEST_FOURCC) );
set_capability( "chroma", 80 );
#elif defined (MODULE_NAME_IS_chroma_i422_yuy2_mmx)
set_description( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) );
set_capability( "chroma", 100 );
add_requirement( MMX );
#endif
set_callbacks( Activate, NULL );
vlc_module_end();
/*****************************************************************************
* Activate: allocate a chroma function
*****************************************************************************
* This function allocates and initializes a chroma function
*****************************************************************************/
static int Activate( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
{
return -1;
}
switch( p_vout->render.i_chroma )
{
case VLC_FOURCC('I','4','2','2'):
switch( p_vout->output.i_chroma )
{
case VLC_FOURCC('Y','U','Y','2'):
case VLC_FOURCC('Y','U','N','V'):
p_vout->chroma.pf_convert = I422_YUY2;
break;
case VLC_FOURCC('Y','V','Y','U'):
p_vout->chroma.pf_convert = I422_YVYU;
break;
case VLC_FOURCC('U','Y','V','Y'):
case VLC_FOURCC('U','Y','N','V'):
case VLC_FOURCC('Y','4','2','2'):
p_vout->chroma.pf_convert = I422_UYVY;
break;
case VLC_FOURCC('I','U','Y','V'):
p_vout->chroma.pf_convert = I422_IUYV;
break;
case VLC_FOURCC('c','y','u','v'):
p_vout->chroma.pf_convert = I422_cyuv;
break;
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
case VLC_FOURCC('Y','2','1','1'):
p_vout->chroma.pf_convert = I422_Y211;
break;
#endif
default:
return -1;
}
break;
default:
return -1;
}
return 0;
}
/* Following functions are local */
/*****************************************************************************
* I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
*****************************************************************************/
static void I422_YUY2( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line = p_dest->p->p_pixels;
u8 *p_y = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
for( i_y = p_vout->render.i_height ; i_y-- ; )
{
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
C_YUV422_YUYV( p_line, p_y, p_u, p_v );
C_YUV422_YUYV( p_line, p_y, p_u, p_v );
C_YUV422_YUYV( p_line, p_y, p_u, p_v );
C_YUV422_YUYV( p_line, p_y, p_u, p_v );
#else
__asm__( ".align 8" MMX_YUV422_YUYV
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV422_YUYV
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
#endif
}
}
}
/*****************************************************************************
* I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
*****************************************************************************/
static void I422_YVYU( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line = p_dest->p->p_pixels;
u8 *p_y = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
for( i_y = p_vout->render.i_height ; i_y-- ; )
{
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
C_YUV422_YVYU( p_line, p_y, p_u, p_v );
C_YUV422_YVYU( p_line, p_y, p_u, p_v );
C_YUV422_YVYU( p_line, p_y, p_u, p_v );
C_YUV422_YVYU( p_line, p_y, p_u, p_v );
#else
__asm__( ".align 8" MMX_YUV422_YVYU
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV422_YVYU
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
#endif
}
}
}
/*****************************************************************************
* I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
*****************************************************************************/
static void I422_UYVY( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line = p_dest->p->p_pixels;
u8 *p_y = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
for( i_y = p_vout->render.i_height ; i_y-- ; )
{
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
#else
__asm__( ".align 8" MMX_YUV422_UYVY
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV422_UYVY
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
#endif
}
}
}
/*****************************************************************************
* I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
*****************************************************************************/
static void I422_IUYV( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
/* FIXME: TODO ! */
msg_Err( p_vout, "I422_IUYV unimplemented, please harass <sam@zoy.org>" );
}
/*****************************************************************************
* I422_cyuv: planar YUV 4:2:2 to upside-down packed UYVY 4:2:2
*****************************************************************************/
static void I422_cyuv( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
u8 *p_y = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
for( i_y = p_vout->render.i_height ; i_y-- ; )
{
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
p_line -= 2 * p_dest->p->i_pitch;
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
C_YUV422_UYVY( p_line, p_y, p_u, p_v );
#else
__asm__( ".align 8" MMX_YUV422_UYVY
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV422_UYVY
: : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
p_line += 8; p_y += 4; p_u += 2; p_v += 2;
#endif
}
}
}
/*****************************************************************************
* I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
*****************************************************************************/
#if defined (MODULE_NAME_IS_chroma_i422_yuy2)
static void I422_Y211( vout_thread_t *p_vout, picture_t *p_source,
picture_t *p_dest )
{
u8 *p_line = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
u8 *p_y = p_source->Y_PIXELS;
u8 *p_u = p_source->U_PIXELS;
u8 *p_v = p_source->V_PIXELS;
int i_x, i_y;
for( i_y = p_vout->render.i_height ; i_y-- ; )
{
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{
C_YUV422_Y211( p_line, p_y, p_u, p_v );
C_YUV422_Y211( p_line, p_y, p_u, p_v );
}
}
}
#endif

View File

@ -1,92 +0,0 @@
/*****************************************************************************
* i422_yuy2.h : YUV to YUV conversion module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: i422_yuy2.h,v 1.1 2002/01/04 14:01:34 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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.
*****************************************************************************/
#ifdef MODULE_NAME_IS_chroma_i422_yuy2_mmx
#define MMX_YUV422_YUYV " \n\
movq (%1), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%2), %%mm1 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%3), %%mm2 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # v3 u3 v2 u2 v1 u1 v0 u0 \n\
movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\
punpcklbw %%mm1, %%mm2 # v1 y3 u1 y2 v0 y1 u0 y0 \n\
movq %%mm2, (%0) # Store low YUYV \n\
punpckhbw %%mm1, %%mm0 # v3 y7 u3 y6 v2 y5 u2 y4 \n\
movq %%mm0, 8(%0) # Store high YUYV \n\
"
#define MMX_YUV422_YVYU " \n\
movq (%1), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%2), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%3), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\
punpcklbw %%mm1, %%mm2 # u1 y3 v1 y2 u0 y1 v0 y0 \n\
movq %%mm2, (%0) # Store low YUYV \n\
punpckhbw %%mm1, %%mm0 # u3 y7 v3 y6 u2 y5 v2 y4 \n\
movq %%mm0, 8(%0) # Store high YUYV \n\
"
#define MMX_YUV422_UYVY " \n\
movq (%1), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%2), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%3), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm1, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm0, %%mm2 # y3 v1 y2 u1 y1 v0 y0 u0 \n\
movq %%mm2, (%0) # Store low UYVY \n\
punpckhbw %%mm0, %%mm1 # y7 v3 y6 u3 y5 v2 y4 u2 \n\
movq %%mm1, 8(%0) # Store high UYVY \n\
"
#define MMX_YUV422_Y211 " \n\
"
#else
#define C_YUV422_YUYV( p_line, p_y, p_u, p_v ) \
*(p_line)++ = *(p_y)++; \
*(p_line)++ = *(p_u)++; \
*(p_line)++ = *(p_y)++; \
*(p_line)++ = *(p_v)++; \
#define C_YUV422_YVYU( p_line, p_y, p_u, p_v ) \
*(p_line)++ = *(p_y)++; \
*(p_line)++ = *(p_v)++; \
*(p_line)++ = *(p_y)++; \
*(p_line)++ = *(p_u)++; \
#define C_YUV422_UYVY( p_line, p_y, p_u, p_v ) \
*(p_line)++ = *(p_u)++; \
*(p_line)++ = *(p_y)++; \
*(p_line)++ = *(p_v)++; \
*(p_line)++ = *(p_y)++; \
#define C_YUV422_Y211( p_line, p_y, p_u, p_v ) \
*(p_line)++ = *(p_y); ((u16*)p_y)++; \
*(p_line)++ = *(p_u) - 0x80; ((u16*)p_u)++; \
*(p_line)++ = *(p_y); ((u16*)p_y)++; \
*(p_line)++ = *(p_v) - 0x80; ((u16*)p_v)++; \
#endif

View File

@ -1,5 +0,0 @@
*.bak
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,2 +0,0 @@
cinepak_SOURCES = cinepak.c

View File

@ -1,966 +0,0 @@
/*****************************************************************************
* cinepak.c: cinepak video decoder
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: cinepak.c,v 1.5 2002/07/31 20:56:51 sam Exp $
*
* Authors: 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
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* getpid() */
#endif
#include <errno.h>
#include <string.h>
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
#include "vdec_ext-plugins.h"
#include "cinepak.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( videodec_thread_t * );
static void EndThread ( videodec_thread_t * );
static void DecodeThread ( videodec_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( "Cinepak video decoder" );
set_capability( "decoder", 70 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
switch( p_fifo->i_fourcc )
{
case VLC_FOURCC('c','v','i','d'):
case VLC_FOURCC('C','V','I','D'):
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
/*****************************************************************************
* RunDecoder: this function is called just after the thread is created
*****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo )
{
videodec_thread_t *p_vdec;
int b_error;
if ( !(p_vdec = (videodec_thread_t*)malloc( sizeof(videodec_thread_t))) )
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
}
memset( p_vdec, 0, sizeof( videodec_thread_t ) );
p_vdec->p_fifo = p_fifo;
if( InitThread( p_vdec ) != 0 )
{
DecoderError( p_fifo );
return( -1 );
}
while( (!p_vdec->p_fifo->b_die) && (!p_vdec->p_fifo->b_error) )
{
DecodeThread( p_vdec );
}
if( ( b_error = p_vdec->p_fifo->b_error ) )
{
DecoderError( p_vdec->p_fifo );
}
EndThread( p_vdec );
if( b_error )
{
return( -1 );
}
return( 0 );
}
/*****************************************************************************
* locales Functions
*****************************************************************************/
static inline u16 GetWBE( u8 *p_buff )
{
return( (p_buff[0]<<8) + p_buff[1] );
}
static inline u32 GetDWBE( u8 *p_buff )
{
return( (p_buff[0] << 24) + ( p_buff[1] <<16 ) +
( p_buff[2] <<8 ) + p_buff[3] );
}
#define GET2BYTES( p ) \
GetWBE( p ); p+= 2;
/* FIXME */
#define GET3BYTES( p ) \
(GetDWBE( p ) >> 8); p+= 3;
#define GET4BYTES( p ) \
GetDWBE( p ); p+= 4;
#define FREE( p ) \
if( p ) free( p )
/* get the first pes from fifo */
static pes_packet_t *__PES_GET( decoder_fifo_t *p_fifo )
{
pes_packet_t *p_pes;
vlc_mutex_lock( &p_fifo->data_lock );
/* if fifo is emty wait */
while( !p_fifo->p_first )
{
if( p_fifo->b_die )
{
vlc_mutex_unlock( &p_fifo->data_lock );
return( NULL );
}
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
p_pes = p_fifo->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
return( p_pes );
}
/* free the first pes and go to next */
static void __PES_NEXT( decoder_fifo_t *p_fifo )
{
pes_packet_t *p_next;
vlc_mutex_lock( &p_fifo->data_lock );
p_next = p_fifo->p_first->p_next;
p_fifo->p_first->p_next = NULL;
input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
p_fifo->p_first = p_next;
p_fifo->i_depth--;
if( !p_fifo->p_first )
{
/* No PES in the fifo */
/* pp_last no longer valid */
p_fifo->pp_last = &p_fifo->p_first;
while( !p_fifo->p_first )
{
vlc_cond_signal( &p_fifo->data_wait );
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
}
vlc_mutex_unlock( &p_fifo->data_lock );
}
static inline void __GetFrame( videodec_thread_t *p_vdec )
{
pes_packet_t *p_pes;
data_packet_t *p_data;
byte_t *p_buffer;
p_pes = __PES_GET( p_vdec->p_fifo );
p_vdec->i_pts = p_pes->i_pts;
while( ( !p_pes->i_nb_data )||( !p_pes->i_pes_size ) )
{
__PES_NEXT( p_vdec->p_fifo );
p_pes = __PES_GET( p_vdec->p_fifo );
}
p_vdec->i_framesize = p_pes->i_pes_size;
if( p_pes->i_nb_data == 1 )
{
p_vdec->p_framedata = p_pes->p_first->p_payload_start;
return;
}
/* get a buffer and gather all data packet */
p_vdec->p_framedata = p_buffer = malloc( p_pes->i_pes_size );
p_data = p_pes->p_first;
do
{
p_vdec->p_fifo->p_vlc->pf_memcpy( p_buffer, p_data->p_payload_start,
p_data->p_payload_end - p_data->p_payload_start );
p_buffer += p_data->p_payload_end - p_data->p_payload_start;
p_data = p_data->p_next;
} while( p_data );
}
static inline void __NextFrame( videodec_thread_t *p_vdec )
{
pes_packet_t *p_pes;
p_pes = __PES_GET( p_vdec->p_fifo );
if( p_pes->i_nb_data != 1 )
{
free( p_vdec->p_framedata ); /* FIXME keep this buffer */
}
__PES_NEXT( p_vdec->p_fifo );
}
static int cinepak_CheckVout( vout_thread_t *p_vout,
int i_width,
int i_height )
{
if( !p_vout )
{
return( 0 );
}
if( ( p_vout->render.i_width != i_width )||
( p_vout->render.i_height != i_height )||
( p_vout->render.i_chroma != VLC_FOURCC('I','4','2','0') )||
( p_vout->render.i_aspect != VOUT_ASPECT_FACTOR * i_width / i_height) )
{
return( 0 );
}
else
{
return( 1 );
}
}
/* Return a Vout */
static vout_thread_t *cinepak_CreateVout( videodec_thread_t *p_vdec,
int i_width,
int i_height )
{
vout_thread_t *p_vout;
if( (!i_width)||(!i_height) )
{
return( NULL ); /* Can't create a new vout without display size */
}
/* Spawn a video output if there is none. First we look for our children,
* then we look for any other vout that might be available. */
p_vout = vlc_object_find( p_vdec->p_fifo, VLC_OBJECT_VOUT,
FIND_CHILD );
if( !p_vout )
{
p_vout = vlc_object_find( p_vdec->p_fifo, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
}
if( p_vout )
{
if( !cinepak_CheckVout( p_vout, i_width, i_height ) )
{
/* We are not interested in this format, close this vout */
vlc_object_detach_all( p_vout );
vlc_object_release( p_vout );
vout_DestroyThread( p_vout );
p_vout = NULL;
}
else
{
/* This video output is cool! Hijack it. */
vlc_object_detach_all( p_vout );
vlc_object_attach( p_vout, p_vdec->p_fifo );
vlc_object_release( p_vout );
}
}
if( p_vout == NULL )
{
msg_Dbg( p_vdec->p_fifo, "no vout present, spawning one" );
p_vout = vout_CreateThread( p_vdec->p_fifo,
i_width,
i_height,
VLC_FOURCC('I','4','2','0'),
VOUT_ASPECT_FACTOR * i_width / i_height );
}
return( p_vout );
}
void cinepak_LoadCodebook( cinepak_codebook_t *p_codebook,
u8 *p_data,
int b_grayscale )
{
int i, i_y[4], i_u, i_v, i_Cb, i_Cr;
int i_uv;
#define SCALEBITS 12
#define FIX( x ) ( (int)( (x) * ( 1L << SCALEBITS ) + 0.5 ) )
for( i = 0; i < 4; i++ )
{
i_y[i] = (u8)( *(p_data++) );
}
if( b_grayscale )
{
i_u = (s8)( *(p_data++) );
i_v = (s8)( *(p_data++) );
}
else
{
i_u = 0;
i_v = 0;
}
/*
| Y | | 1 -0.0655 0.0110 | | CY |
| Cb | = | 0 1.1656 -0.0062 | | CU |
| Cr | | 0 0.0467 1.4187 | | CV |
*/
i_uv = ( FIX( -0.0655 ) * i_u + FIX( 0.0110 ) * i_v ) >> SCALEBITS;
for( i = 0; i < 4; i++ )
{
i_y[i] += i_uv;
}
i_Cb = ( FIX( 1.1656 ) * i_u + FIX( -0.0062 ) * i_v ) >> SCALEBITS;
i_Cr = ( FIX( 0.0467 ) * i_u + FIX( 1.4187 ) * i_v ) >> SCALEBITS;
for( i = 0; i < 4; i++ )
{
p_codebook->i_y[i] = __MIN( __MAX( 0, i_y[i] ), 255 );
}
p_codebook->i_u = __MIN( __MAX( 0, i_Cb + 128 ), 255 );
p_codebook->i_v = __MIN( __MAX( 0, i_Cr + 128 ), 255 );
#undef FIX
#undef SCALEBITS
}
void cinepak_Getv4( cinepak_context_t *p_context,
int i_strip,
int i_x, int i_y,
int i_x2, int i_y2,
u8 *p_data )
{
u8 i_index[4];
int i,j;
u8 *p_dst_y, *p_dst_u, *p_dst_v;
#define PIX_SET_Y( x, y, v ) \
p_dst_y[(x) + (y)* p_context->i_stride[0]] = (v);
#define PIX_SET_UV( i, p, x, y, v ) \
p[(x) + (y)* (p_context->i_stride[i])] = (v);
for( i = 0; i < 4; i++ )
{
i_index[i] = *(p_data++);
}
/* y plane */
p_dst_y = p_context->p_pix[0] + p_context->i_stride[0] * i_y + i_x;
p_dst_u = p_context->p_pix[1] + p_context->i_stride[1] * (i_y/2) + (i_x/2);
p_dst_v = p_context->p_pix[2] + p_context->i_stride[2] * (i_y/2) + (i_x/2);
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 2; j ++ )
{
PIX_SET_Y( 2*j + 0, 2*i + 0,
p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[0]);
PIX_SET_Y( 2*j + 1, 2*i + 0,
p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[1]);
PIX_SET_Y( 2*j + 0, 2*i + 1,
p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[2]);
PIX_SET_Y( 2*j + 1, 2*i + 1,
p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[3]);
PIX_SET_UV( 1, p_dst_u, j, i,
p_context->codebook_v4[i_strip][i_index[j+2*i]].i_u );
PIX_SET_UV( 2, p_dst_v, j, i,
p_context->codebook_v4[i_strip][i_index[j+2*i]].i_v );
}
}
#undef PIX_SET_Y
#undef PIX_SET_UV
}
void cinepak_Getv1( cinepak_context_t *p_context,
int i_strip,
int i_x, int i_y,
int i_x2, int i_y2,
u8 *p_data )
{
u8 i_index;
int i,j;
u8 *p_dst_y, *p_dst_u, *p_dst_v;
#define PIX_SET_Y( x, y, v ) \
p_dst_y[(x) + (y)* p_context->i_stride[0]] = (v);
#define PIX_SET_UV( i,p, x, y, v ) \
p[(x) + (y)* (p_context->i_stride[i])] = (v);
i_index = *(p_data++);
/* y plane */
p_dst_y = p_context->p_pix[0] + p_context->i_stride[0] * i_y + i_x;
p_dst_u = p_context->p_pix[1] + p_context->i_stride[1] * (i_y/2) + (i_x/2);
p_dst_v = p_context->p_pix[2] + p_context->i_stride[2] * (i_y/2) + (i_x/2);
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 2; j ++ )
{
PIX_SET_Y( 2*j + 0, 2*i + 0,
p_context->codebook_v1[i_strip][i_index].i_y[0] );
PIX_SET_Y( 2*j + 1, 2*i + 0,
p_context->codebook_v1[i_strip][i_index].i_y[1] );
PIX_SET_Y( 2*j + 0, 2*i + 1,
p_context->codebook_v1[i_strip][i_index].i_y[2] );
PIX_SET_Y( 2*j + 1, 2*i + 1,
p_context->codebook_v1[i_strip][i_index].i_y[3] );
PIX_SET_UV( 1,p_dst_u, j, i,
p_context->codebook_v1[i_strip][i_index].i_u );
PIX_SET_UV( 2,p_dst_v, j, i,
p_context->codebook_v1[i_strip][i_index].i_v );
}
}
#undef PIX_SET_Y
#undef PIX_SET_UV
}
/*****************************************************************************
* The function that decode one frame
*****************************************************************************/
int cinepak_decode_frame( cinepak_context_t *p_context,
int i_length, u8 *p_data )
{
int i_strip;
int i_frame_flags;
int i_frame_size;
int i_width, i_height;
int i_frame_strips;
int i_index;
int i_strip_x1 =0, i_strip_y1=0;
int i_strip_x2 =0, i_strip_y2=0;
if( i_length <= 10 )
{
/* Broken header or no data */
return( -1 );
}
/* get header */
i_frame_flags = *(p_data++);
i_frame_size = GET3BYTES( p_data );
i_width = GET2BYTES( p_data );
i_height = GET2BYTES( p_data );
i_frame_strips = GET2BYTES( p_data );
/* Check if we have a picture buffer with good size */
if( ( p_context->i_width != i_width )||
( p_context->i_height != i_height ) )
{
int i;
for( i = 0; i < 3; i++ )
{
FREE( p_context->p_pix[i] );
}
p_context->i_width = i_width;
p_context->i_height = i_height;
p_context->i_stride[0] = ( i_width + 3)&0xfffc;
p_context->i_stride[1] = p_context->i_stride[2] =
p_context->i_stride[0] / 2;
p_context->i_lines[0] = ( i_height + 3 )&0xfffc;
p_context->i_lines[1] = p_context->i_lines[2] =
p_context->i_lines[0] /2;
for( i = 0; i < 3; i++ )
{
p_context->p_pix[i] = malloc( p_context->i_stride[i] *
p_context->i_lines[i] );
}
}
if( i_frame_size != i_length )
{
i_length = __MIN( i_length, i_frame_size );
}
i_length -= 10;
if( i_frame_strips >= CINEPAK_MAXSTRIP )
{
i_frame_strips = CINEPAK_MAXSTRIP;
}
/* Now decode each strip */
for( i_strip = 0; i_strip < i_frame_strips; i_strip++ )
{
int i_strip_id;
int i_strip_size;
if( i_length <= 12 )
{
break;
}
i_strip_id = GET2BYTES( p_data );
i_strip_size = GET2BYTES( p_data );
i_strip_size = __MIN( i_strip_size, i_length );
/* FIXME I don't really understand how it's work; */
i_strip_y1 = i_strip_y2 + GET2BYTES( p_data );
i_strip_x1 = GET2BYTES( p_data );
i_strip_y2 = i_strip_y2 + GET2BYTES( p_data );
i_strip_x2 = GET2BYTES( p_data );
i_length -= i_strip_size;
i_strip_size -= 12;
/* init codebook , if needed */
if( ( i_strip > 0 )&&( !(i_frame_flags&0x01) ) )
{
memcpy( &p_context->codebook_v1[i_strip],
&p_context->codebook_v1[i_strip-1],
sizeof(cinepak_codebook_t[256] ) );
memcpy( &p_context->codebook_v4[i_strip],
&p_context->codebook_v4[i_strip-1],
sizeof(cinepak_codebook_t[256] ) );
}
/* Now parse all chunk in this strip */
while( i_strip_size > 0 )
{
cinepak_codebook_t (*p_codebook)[CINEPAK_MAXSTRIP][256];
int i_mode;
int i_chunk_id;
int i_chunk_size;
u32 i_vector_flags;
int i_count;
int i;
int i_x, i_y; /* (0,0) begin in fact at (x1,y1) ... */
i_chunk_id = GET2BYTES( p_data );
i_chunk_size = GET2BYTES( p_data );
i_chunk_size = __MIN( i_chunk_size, i_strip_size );
i_strip_size -= i_chunk_size;
i_chunk_size -= 4;
i_x = 0;
i_y = 0;
if( i_chunk_size < 0 )
{
break;
}
switch( i_chunk_id )
{
case( 0x2000 ): /* 12bits v4 Intra*/
case( 0x2200 ): /* 12bits v1 Intra*/
case( 0x2400 ): /* 8bits v4 Intra*/
case( 0x2600 ): /* 8bits v1 Intra */
i_mode = ( ( i_chunk_id&0x0400 ) == 0 );
p_codebook = ( i_chunk_id&0x0200 ) ?
&p_context->codebook_v1 :
&p_context->codebook_v4;
i_count = __MIN( i_chunk_size / ( i_mode ? 6 : 4 ), 256 );
for( i = 0; i < i_count; i++ )
{
cinepak_LoadCodebook( &((*p_codebook)[i_strip][i]),
p_data,
i_mode&~p_context->b_grayscale );
p_data += i_mode ? 6 : 4;
i_chunk_size -= i_mode ? 6 : 4;
}
break;
case( 0x2100 ): /* selective 12bits v4 Inter*/
case( 0x2300 ): /* selective 12bits v1 Inter*/
case( 0x2500 ): /* selective 8bits v4 Inter*/
case( 0x2700 ): /* selective 8bits v1 Inter*/
i_mode = ( ( i_chunk_id&0x0400 ) == 0 );
p_codebook = ( i_chunk_id&0x0200 ) ?
&p_context->codebook_v1 :
&p_context->codebook_v4;
i_index = 0;
while( (i_chunk_size > 4)&&(i_index<256))
{
i_vector_flags = GET4BYTES( p_data );
i_chunk_size -= 4;
for( i = 0; i < 32; i++ )
{
if( ( i_chunk_size < ( i_mode ? 6 : 4 ) )||(i_index >= 256 ))
{
break;
}
if( i_vector_flags&0x80000000UL )
{
cinepak_LoadCodebook( &((*p_codebook)[i_strip][i_index]),
p_data,
i_mode&~p_context->b_grayscale );
p_data += i_mode ? 6 : 4;
i_chunk_size -= i_mode ? 6 : 4;
}
i_index++;
i_vector_flags <<= 1;
}
}
break;
case( 0x3000 ): /* load image Intra */
while( (i_chunk_size >= 4 )&&(i_y<i_strip_y2-i_strip_y1) )
{
i_vector_flags = GET4BYTES( p_data );
i_chunk_size -= 4;
i_strip_size -= 4;
i_length -= 4;
for( i = 0; i < 32; i++ )
{
if( ( i_y >= i_strip_y2 - i_strip_y1)||
( i_chunk_size<=0) )
{
break;
}
if( i_vector_flags&0x80000000UL )
{
cinepak_Getv4( p_context,
i_strip,
i_strip_x1 + i_x,
i_strip_y1 + i_y,
i_strip_x2, i_strip_y2,
p_data );
p_data += 4;
i_chunk_size -= 4;
}
else
{
cinepak_Getv1( p_context,
i_strip,
i_strip_x1 + i_x,
i_strip_y1 + i_y,
i_strip_x2, i_strip_y2,
p_data );
p_data++;
i_chunk_size--;
}
i_x += 4;
if( i_x >= i_strip_x2 - i_strip_x1 )
{
i_x = 0;
i_y += 4;
}
i_vector_flags <<= 1;
}
}
break;
case( 0x3100 ): /* load image Inter */
while( ( i_chunk_size > 4 )&&( i_y < i_strip_y2 - i_strip_y1) )
{
u32 i_mask;
i_vector_flags = GET4BYTES( p_data );
i_chunk_size -= 4;
i_mask = 0x80000000UL;
while((i_chunk_size > 0 )&&( i_mask )&&( i_y < i_strip_y2 - i_strip_y1 ))
{
if( i_vector_flags&i_mask)
{
i_mask >>= 1;
if( !i_mask )
{
if( i_chunk_size < 4 )
{
break;
}
i_vector_flags = GET4BYTES( p_data );
i_chunk_size -= 4;
i_mask = 0x80000000UL;
}
if( i_vector_flags&i_mask )
{
if( i_chunk_size < 4 ) break;
cinepak_Getv4( p_context,
i_strip,
i_strip_x1 + i_x,
i_strip_y1 + i_y,
i_strip_x2, i_strip_y2,
p_data );
p_data += 4;
i_chunk_size -= 4;
}
else
{
if( i_chunk_size < 1 ) break;
cinepak_Getv1( p_context,
i_strip,
i_strip_x1 + i_x,
i_strip_y1 + i_y,
i_strip_x2, i_strip_y2,
p_data );
p_data++;
i_chunk_size--;
}
}
i_mask >>= 1;
i_x += 4;
if( i_x >= i_strip_x2 - i_strip_x1 )
{
i_x = 0;
i_y += 4;
}
}
}
break;
case( 0x3200 ): /* load intra picture but all v1*/
while( ( i_chunk_size > 0 )&&
( i_y < i_strip_y2 - i_strip_y1) )
{
cinepak_Getv1( p_context,
i_strip,
i_strip_x1 + i_x,
i_strip_y1 + i_y,
i_strip_x2, i_strip_y2,
p_data );
p_data++;
i_chunk_size--;
i_x += 4;
if( i_x >= i_strip_x2 - i_strip_x1 )
{
i_x = 0;
i_y += 4;
}
}
break;
default:
break;
}
p_data += i_chunk_size ; /* skip remains bytes */
}
}
return( 0 );
}
/*****************************************************************************
*
* Functions that initialize, decode and end the decoding process
*
*****************************************************************************/
/*****************************************************************************
* InitThread: initialize vdec output thread
*****************************************************************************
* This function is called from decoder_Run and performs the second step
* of the initialization. It returns 0 on success. Note that the thread's
* flag are not modified inside this function.
*****************************************************************************/
static int InitThread( videodec_thread_t *p_vdec )
{
/* This will be created after the first decoded frame */
if( !(p_vdec->p_context = malloc( sizeof( cinepak_context_t ) ) ) )
{
msg_Err( p_vdec->p_fifo, "out of memory" );
}
memset( p_vdec->p_context, 0, sizeof( cinepak_context_t ) );
if( config_GetInt( p_vdec->p_fifo, "grayscale" ) )
{
p_vdec->p_context->b_grayscale = 1;
}
else
{
p_vdec->p_context->b_grayscale = 0;
}
p_vdec->p_vout = NULL;
msg_Dbg( p_vdec->p_fifo, "cinepak decoder started" );
return( 0 );
}
/*****************************************************************************
* DecodeThread: Called for decode one frame
*****************************************************************************/
static void DecodeThread( videodec_thread_t *p_vdec )
{
int i_status;
int i_plane;
u8 *p_dst, *p_src;
picture_t *p_pic; /* videolan picture */
__GetFrame( p_vdec );
i_status = cinepak_decode_frame( p_vdec->p_context,
p_vdec->i_framesize,
p_vdec->p_framedata );
__NextFrame( p_vdec );
if( i_status < 0 )
{
msg_Warn( p_vdec->p_fifo, "cannot decode one frame (%d bytes)",
p_vdec->i_framesize );
return;
}
/* Check our vout */
if( !cinepak_CheckVout( p_vdec->p_vout,
p_vdec->p_context->i_width,
p_vdec->p_context->i_height ) )
{
p_vdec->p_vout =
cinepak_CreateVout( p_vdec,
p_vdec->p_context->i_width,
p_vdec->p_context->i_height );
if( !p_vdec->p_vout )
{
msg_Err( p_vdec->p_fifo, "cannot create vout" );
p_vdec->p_fifo->b_error = 1; /* abort */
return;
}
}
/* Send decoded frame to vout */
while( !(p_pic = vout_CreatePicture( p_vdec->p_vout, 0, 0, 0 ) ) )
{
if( p_vdec->p_fifo->b_die || p_vdec->p_fifo->b_error )
{
return;
}
msleep( VOUT_OUTMEM_SLEEP );
}
for( i_plane = 0; i_plane < 3; i_plane++ )
{
int i_line, i_lines;
p_dst = p_pic->p[i_plane].p_pixels;
p_src = p_vdec->p_context->p_pix[i_plane];
i_lines = __MIN( p_vdec->p_context->i_lines[i_plane],
p_pic->p[i_plane].i_lines );
for( i_line = 0; i_line < i_lines; i_line++ )
{
memcpy( p_dst,
p_src,
__MIN( p_pic->p[i_plane].i_pitch,
p_vdec->p_context->i_stride[i_plane] ) );
p_dst += p_pic->p[i_plane].i_pitch;
p_src += p_vdec->p_context->i_stride[i_plane];
}
}
vout_DatePicture( p_vdec->p_vout, p_pic, p_vdec->i_pts);
vout_DisplayPicture( p_vdec->p_vout, p_pic );
return;
}
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
* This function is called when the thread ends after a sucessful
* initialization.
*****************************************************************************/
static void EndThread( videodec_thread_t *p_vdec )
{
int i;
if( !p_vdec )
{
return;
}
msg_Dbg( p_vdec->p_fifo, "cinepak decoder stopped" );
for( i = 0; i < 3; i++ )
{
FREE( p_vdec->p_context->p_pix[i] );
}
free( p_vdec->p_context );
if( p_vdec->p_vout != NULL )
{
/* We are about to die. Reattach video output to p_vlc. */
vlc_object_detach( p_vdec->p_vout, p_vdec->p_fifo );
vlc_object_attach( p_vdec->p_vout, p_vdec->p_fifo->p_vlc );
}
free( p_vdec );
}

View File

@ -1,67 +0,0 @@
/*****************************************************************************
* cinepak.h: Cinepak video decoder
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: cinepak.h,v 1.2 2002/07/21 18:47:22 fenrir Exp $
*
* Authors: 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.
*****************************************************************************/
#define CINEPAK_MAXSTRIP 32
typedef struct cinepak_codebook_s
{
u8 i_y[4];
u8 i_u, i_v;
} cinepak_codebook_t;
typedef struct cinepak_context_s
{
int b_grayscale; /* force to grayscale */
int i_width;
int i_height;
int i_stride_x;
int i_stride_y;
u8 *p_y, *p_u, *p_v;
int i_stride[3]; /* our 3 planes */
int i_lines[3];
u8 *p_pix[3];
cinepak_codebook_t codebook_v1[CINEPAK_MAXSTRIP][256];
cinepak_codebook_t codebook_v4[CINEPAK_MAXSTRIP][256];
} cinepak_context_t;
typedef struct videodec_thread_s
{
decoder_fifo_t *p_fifo;
vout_thread_t *p_vout;
cinepak_context_t *p_context;
/* private */
mtime_t i_pts;
int i_framesize;
byte_t *p_framedata;
} videodec_thread_t;

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1 +0,0 @@
directx_SOURCES = directx.c vout_directx.c vout_events.c aout_directx.c

View File

@ -1,761 +0,0 @@
/*****************************************************************************
* aout_directx.c: Windows DirectX audio output method
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: aout_directx.c,v 1.26 2002/07/31 20:56:51 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <fcntl.h> /* open(), O_WRONLY */
#include <string.h> /* strerror() */
#include <stdlib.h> /* calloc(), malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <mmsystem.h>
#include <dsound.h>
/*****************************************************************************
* DirectSound GUIDs.
* Defining them here allows us to get rid of the dxguid library during
* the linking stage.
*****************************************************************************/
#include <initguid.h>
DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16);
/*****************************************************************************
* notification_thread_t: DirectX event thread
*****************************************************************************/
typedef struct notification_thread_t
{
VLC_COMMON_MEMBERS
aout_thread_t * p_aout;
DSBPOSITIONNOTIFY p_events[2]; /* play notification events */
} notification_thread_t;
/*****************************************************************************
* aout_sys_t: directx audio output method descriptor
*****************************************************************************
* This structure is part of the audio output thread descriptor.
* It describes the direct sound specific properties of an audio device.
*****************************************************************************/
struct aout_sys_t
{
LPDIRECTSOUND p_dsobject; /* main Direct Sound object */
LPDIRECTSOUNDBUFFER p_dsbuffer_primary; /* the actual sound card buffer
(not used directly) */
LPDIRECTSOUNDBUFFER p_dsbuffer; /* the sound buffer we use (direct sound
* takes care of mixing all the
* secondary buffers into the primary) */
LPDIRECTSOUNDNOTIFY p_dsnotify; /* the position notify interface */
HINSTANCE hdsound_dll; /* handle of the opened dsound dll */
long l_buffer_size; /* secondary sound buffer size */
long l_write_position; /* next write position for the buffer */
volatile vlc_bool_t b_buffer_underflown; /* buffer underflow detection */
volatile long l_data_played_from_beginning; /* for underflow detection */
volatile long l_data_written_from_beginning; /* for underflow detection */
vlc_mutex_t buffer_lock; /* audio buffer lock */
notification_thread_t * p_notif; /* DirectSoundThread id */
};
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int SetFormat ( aout_thread_t * );
static int GetBufInfo ( aout_thread_t *, int );
static void Play ( aout_thread_t *, byte_t *, int );
/* local functions */
static int DirectxCreateSecondaryBuffer ( aout_thread_t * );
static void DirectxDestroySecondaryBuffer( aout_thread_t * );
static int DirectxInitDSound ( aout_thread_t * );
static void DirectSoundThread ( notification_thread_t * );
/*****************************************************************************
* OpenAudio: open the audio device
*****************************************************************************
* This function opens and setups Direct Sound.
*****************************************************************************/
int E_(OpenAudio) ( vlc_object_t *p_this )
{
aout_thread_t * p_aout = (aout_thread_t *)p_this;
HRESULT dsresult;
DSBUFFERDESC dsbuffer_desc;
msg_Dbg( p_aout, "Open" );
/* Allocate structure */
p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
if( p_aout->p_sys == NULL )
{
msg_Err( p_aout, "out of memory" );
return( 1 );
}
/* Initialize some variables */
p_aout->p_sys->p_dsobject = NULL;
p_aout->p_sys->p_dsbuffer_primary = NULL;
p_aout->p_sys->p_dsbuffer = NULL;
p_aout->p_sys->p_dsnotify = NULL;
p_aout->p_sys->l_data_written_from_beginning = 0;
p_aout->p_sys->l_data_played_from_beginning = 0;
vlc_mutex_init( p_aout, &p_aout->p_sys->buffer_lock );
p_aout->pf_setformat = SetFormat;
p_aout->pf_getbufinfo = GetBufInfo;
p_aout->pf_play = Play;
/* Initialise DirectSound */
if( DirectxInitDSound( p_aout ) )
{
msg_Warn( p_aout, "cannot initialize DirectSound" );
return( 1 );
}
/* Obtain (not create) Direct Sound primary buffer */
memset( &dsbuffer_desc, 0, sizeof(DSBUFFERDESC) );
dsbuffer_desc.dwSize = sizeof(DSBUFFERDESC);
dsbuffer_desc.dwFlags = DSBCAPS_PRIMARYBUFFER;
msg_Warn( p_aout, "create direct sound primary buffer" );
dsresult = IDirectSound_CreateSoundBuffer(p_aout->p_sys->p_dsobject,
&dsbuffer_desc,
&p_aout->p_sys->p_dsbuffer_primary,
NULL);
if( dsresult != DS_OK )
{
msg_Warn( p_aout, "cannot create direct sound primary buffer" );
IDirectSound_Release( p_aout->p_sys->p_dsobject );
p_aout->p_sys->p_dsobject = NULL;
p_aout->p_sys->p_dsbuffer_primary = NULL;
return( 1 );
}
/* Now we need to setup DirectSound play notification */
/* first we need to create the notification events */
p_aout->p_sys->p_notif->p_events[0].hEventNotify =
CreateEvent( NULL, FALSE, FALSE, NULL );
p_aout->p_sys->p_notif->p_events[1].hEventNotify =
CreateEvent( NULL, FALSE, FALSE, NULL );
/* then launch the notification thread */
msg_Dbg( p_aout, "creating DirectSoundThread" );
p_aout->p_sys->p_notif =
vlc_object_create( p_aout, sizeof(notification_thread_t) );
p_aout->p_sys->p_notif->p_aout = p_aout;
if( vlc_thread_create( p_aout->p_sys->p_notif,
"DirectSound Notification Thread", DirectSoundThread, 1 ) )
{
msg_Err( p_aout, "cannot create DirectSoundThread" );
/* Let's go on anyway */
}
vlc_object_attach( p_aout->p_sys->p_notif, p_aout );
return( 0 );
}
/*****************************************************************************
* SetFormat: reset the audio device and sets its format
*****************************************************************************
* This functions set a new audio format.
* For this we need to close the current secondary buffer and create another
* one with the desired format.
*****************************************************************************/
static int SetFormat( aout_thread_t *p_aout )
{
HRESULT dsresult;
WAVEFORMATEX *p_waveformat;
unsigned long i_size_struct;
msg_Dbg( p_aout, "SetFormat" );
/* Set the format of Direct Sound primary buffer */
/* first we need to know the current format */
dsresult = IDirectSoundBuffer_GetFormat( p_aout->p_sys->p_dsbuffer_primary,
NULL, 0, &i_size_struct );
if( dsresult == DS_OK )
{
p_waveformat = malloc( i_size_struct );
dsresult = IDirectSoundBuffer_GetFormat(
p_aout->p_sys->p_dsbuffer_primary,
p_waveformat, i_size_struct,
NULL );
}
if( dsresult == DS_OK )
{
/* Here we'll change the format */
p_waveformat->nChannels = 2;
p_waveformat->nSamplesPerSec = (p_aout->i_rate < 44100) ? 44100
: p_aout->i_rate;
p_waveformat->wBitsPerSample = 16;
p_waveformat->nBlockAlign = p_waveformat->wBitsPerSample / 8 *
p_waveformat->nChannels;
p_waveformat->nAvgBytesPerSec = p_waveformat->nSamplesPerSec *
p_waveformat->nBlockAlign;
dsresult = IDirectSoundBuffer_SetFormat(
p_aout->p_sys->p_dsbuffer_primary,
p_waveformat );
}
else msg_Warn( p_aout, "cannot get primary buffer format" );
if( dsresult != DS_OK )
msg_Warn( p_aout, "cannot set primary buffer format" );
/* Now we need to take care of Direct Sound secondary buffer */
vlc_mutex_lock( &p_aout->p_sys->buffer_lock );
/* first release the current secondary buffer */
DirectxDestroySecondaryBuffer( p_aout );
/* then create a new secondary buffer */
if( DirectxCreateSecondaryBuffer( p_aout ) )
{
msg_Warn( p_aout, "cannot create buffer" );
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return( 1 );
}
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return( 0 );
}
/*****************************************************************************
* GetBufInfo: buffer status query
*****************************************************************************
* returns the number of bytes in the audio buffer that have not yet been
* sent to the sound device.
*****************************************************************************/
static int GetBufInfo( aout_thread_t *p_aout, int i_buffer_limit )
{
long l_play_position, l_notused, l_result;
HRESULT dsresult;
if( p_aout->p_sys->b_buffer_underflown )
{
msg_Warn( p_aout, "GetBufInfo underflow" );
return( i_buffer_limit );
}
dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer,
&l_play_position, &l_notused);
if( dsresult != DS_OK )
{
msg_Warn( p_aout, "GetBufInfo cannot get current pos" );
return( i_buffer_limit );
}
l_result = (p_aout->p_sys->l_write_position >= l_play_position) ?
(p_aout->p_sys->l_write_position - l_play_position)
: (p_aout->p_sys->l_buffer_size - l_play_position
+ p_aout->p_sys->l_write_position);
#if 0
msg_Dbg( p_aout, "GetBufInfo: %i", i_result);
#endif
return l_result;
}
/*****************************************************************************
* Play: play a sound buffer
*****************************************************************************
* This function writes a buffer of i_length bytes
* Don't forget that DirectSound buffers are circular buffers.
*****************************************************************************/
static void Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
VOID *p_write_position, *p_start_buffer;
long l_bytes1, l_bytes2, l_play_position;
HRESULT dsresult;
/* protect buffer access (because of DirectSoundThread) */
vlc_mutex_lock( &p_aout->p_sys->buffer_lock );
if( p_aout->p_sys->b_buffer_underflown )
{
/* there has been an underflow so we need to play the new sample
* as soon as possible. This is why we query the play position */
dsresult = IDirectSoundBuffer_GetCurrentPosition(
p_aout->p_sys->p_dsbuffer,
&l_play_position,
&p_aout->p_sys->l_write_position );
if( dsresult != DS_OK )
{
msg_Warn( p_aout, "cannot get buffer position" );
p_aout->p_sys->l_write_position = 0;
}
msg_Warn( p_aout, "Play underflow" );
/* reinitialise the underflow detection counters */
p_aout->p_sys->b_buffer_underflown = 0;
p_aout->p_sys->l_data_written_from_beginning = 0;
#define WRITE_P p_aout->p_sys->l_write_position
#define PLAY_P l_play_position
#define BUF_SIZE p_aout->p_sys->l_buffer_size
p_aout->p_sys->l_data_played_from_beginning = -(WRITE_P %(BUF_SIZE/2));
if( PLAY_P < BUF_SIZE/2 && WRITE_P > BUF_SIZE/2 )
{
p_aout->p_sys->l_data_played_from_beginning -= (BUF_SIZE/2);
}
if( PLAY_P > BUF_SIZE/2 && WRITE_P < BUF_SIZE/2 )
{
p_aout->p_sys->l_data_played_from_beginning -= (BUF_SIZE/2);
}
#undef WRITE_P
#undef PLAY_P
#undef BUF_SIZE
}
/* Before copying anything, we have to lock the buffer */
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
p_aout->p_sys->l_write_position, /* Offset of lock start */
i_size, /* Number of bytes to lock */
&p_write_position, /* Address of lock start */
&l_bytes1, /* Count of bytes locked before wrap around */
&p_start_buffer, /* Buffer adress (if wrap around) */
&l_bytes2, /* Count of bytes after wrap around */
0); /* Flags */
if( dsresult == DSERR_BUFFERLOST )
{
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
p_aout->p_sys->l_write_position,
i_size,
&p_write_position,
&l_bytes1,
&p_start_buffer,
&l_bytes2,
0);
}
if( dsresult != DS_OK )
{
msg_Warn( p_aout, "Play cannot lock buffer" );
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return;
}
/* Now do the actual memcpy (two memcpy because the buffer is circular) */
memcpy( p_write_position, buffer, l_bytes1 );
if( p_start_buffer != NULL )
{
memcpy( p_start_buffer, buffer + l_bytes1, l_bytes2 );
}
/* Now the data has been copied, unlock the buffer */
IDirectSoundBuffer_Unlock( p_aout->p_sys->p_dsbuffer,
p_write_position, l_bytes1, p_start_buffer, l_bytes2 );
/* Update the write position index of the buffer*/
p_aout->p_sys->l_write_position += i_size;
p_aout->p_sys->l_write_position %= p_aout->p_sys->l_buffer_size;
p_aout->p_sys->l_data_written_from_beginning += i_size;
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
/* The play function has no effect if the buffer is already playing */
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer,
0, /* Unused */
0, /* Unused */
DSBPLAY_LOOPING ); /* Flags */
if( dsresult == DSERR_BUFFERLOST )
{
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer,
0, /* Unused */
0, /* Unused */
DSBPLAY_LOOPING ); /* Flags */
}
if( dsresult != DS_OK )
{
msg_Warn( p_aout, "Play cannot play buffer" );
return;
}
}
/*****************************************************************************
* CloseAudio: close the audio device
*****************************************************************************/
void E_(CloseAudio) ( vlc_object_t *p_this )
{
aout_thread_t * p_aout = (aout_thread_t *)p_this;
msg_Dbg( p_aout, "Close" );
/* kill the position notification thread, if any */
vlc_object_detach_all( p_aout->p_sys->p_notif );
if( p_aout->p_sys->p_notif->b_thread )
{
p_aout->p_sys->p_notif->b_die = 1;
vlc_thread_join( p_aout->p_sys->p_notif );
}
vlc_object_destroy( p_aout->p_sys->p_notif );
/* release the secondary buffer */
DirectxDestroySecondaryBuffer( p_aout );
/* then release the primary buffer */
if( p_aout->p_sys->p_dsbuffer_primary != NULL )
{
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer_primary );
p_aout->p_sys->p_dsbuffer_primary = NULL;
}
/* finally release the DirectSound object */
if( p_aout->p_sys->p_dsobject != NULL )
{
IDirectSound_Release( p_aout->p_sys->p_dsobject );
p_aout->p_sys->p_dsobject = NULL;
}
/* free DSOUND.DLL */
if( p_aout->p_sys->hdsound_dll != NULL )
{
FreeLibrary( p_aout->p_sys->hdsound_dll );
p_aout->p_sys->hdsound_dll = NULL;
}
/* Close the Output. */
if ( p_aout->p_sys != NULL )
{
free( p_aout->p_sys );
p_aout->p_sys = NULL;
}
}
/*****************************************************************************
* DirectxInitDSound
*****************************************************************************
*****************************************************************************/
static int DirectxInitDSound( aout_thread_t *p_aout )
{
HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
p_aout->p_sys->hdsound_dll = LoadLibrary("DSOUND.DLL");
if( p_aout->p_sys->hdsound_dll == NULL )
{
msg_Warn( p_aout, "cannot open DSOUND.DLL" );
return( 1 );
}
OurDirectSoundCreate = (void *)GetProcAddress( p_aout->p_sys->hdsound_dll,
"DirectSoundCreate" );
if( OurDirectSoundCreate == NULL )
{
msg_Warn( p_aout, "GetProcAddress FAILED" );
FreeLibrary( p_aout->p_sys->hdsound_dll );
p_aout->p_sys->hdsound_dll = NULL;
return( 1 );
}
/* Create the direct sound object */
if( OurDirectSoundCreate(NULL, &p_aout->p_sys->p_dsobject, NULL) != DS_OK )
{
msg_Warn( p_aout, "cannot create a direct sound device" );
p_aout->p_sys->p_dsobject = NULL;
FreeLibrary( p_aout->p_sys->hdsound_dll );
p_aout->p_sys->hdsound_dll = NULL;
return( 1 );
}
/* Set DirectSound Cooperative level, ie what control we want over Windows
* sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the
* settings of the primary buffer, but also that only the sound of our
* application will be hearable when it will have the focus.
* !!! (this is not really working as intended yet because to set the
* cooperative level you need the window handle of your application, and
* I don't know of any easy way to get it. Especially since we might play
* sound without any video, and so what window handle should we use ???
* The hack for now is to use the Desktop window handle - it seems to be
* working */
if( IDirectSound_SetCooperativeLevel(p_aout->p_sys->p_dsobject,
GetDesktopWindow(),
DSSCL_EXCLUSIVE) )
{
msg_Warn( p_aout, "cannot set direct sound cooperative level" );
}
return( 0 );
}
/*****************************************************************************
* DirectxCreateSecondaryBuffer
*****************************************************************************
* This function creates the buffer we'll use to play audio.
* In DirectSound there are two kinds of buffers:
* - the primary buffer: which is the actual buffer that the soundcard plays
* - the secondary buffer(s): these buffers are the one actually used by
* applications and DirectSound takes care of mixing them into the primary.
*
* Once you create a secondary buffer, you cannot change its format anymore so
* you have to release the current and create another one.
*****************************************************************************/
static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout )
{
WAVEFORMATEX waveformat;
DSBUFFERDESC dsbdesc;
DSBCAPS dsbcaps;
/* First set the buffer format */
memset(&waveformat, 0, sizeof(WAVEFORMATEX));
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.nChannels = p_aout->i_channels;
waveformat.nSamplesPerSec = p_aout->i_rate;
waveformat.wBitsPerSample = 16;
waveformat.nBlockAlign = waveformat.wBitsPerSample / 8 *
waveformat.nChannels;
waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec *
waveformat.nBlockAlign;
/* Then fill in the descriptor */
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
| DSBCAPS_CTRLPOSITIONNOTIFY /* We need notification */
| DSBCAPS_GLOBALFOCUS; /* Allows background playing */
dsbdesc.dwBufferBytes = waveformat.nAvgBytesPerSec * 2; /* 2 sec buffer */
dsbdesc.lpwfxFormat = &waveformat;
if( IDirectSound_CreateSoundBuffer( p_aout->p_sys->p_dsobject,
&dsbdesc,
&p_aout->p_sys->p_dsbuffer,
NULL) != DS_OK )
{
msg_Warn( p_aout, "cannot create direct sound secondary buffer" );
p_aout->p_sys->p_dsbuffer = NULL;
return( 1 );
}
/* backup the size of the secondary sound buffer */
memset(&dsbcaps, 0, sizeof(DSBCAPS));
dsbcaps.dwSize = sizeof(DSBCAPS);
IDirectSoundBuffer_GetCaps( p_aout->p_sys->p_dsbuffer, &dsbcaps );
p_aout->p_sys->l_buffer_size = dsbcaps.dwBufferBytes;
p_aout->p_sys->l_write_position = 0;
msg_Dbg( p_aout, "DirectxCreateSecondaryBuffer: %li",
p_aout->p_sys->l_buffer_size );
/* Now the secondary buffer is created, we need to setup its position
* notification */
p_aout->p_sys->p_notif->p_events[0].dwOffset = 0; /* notif position */
p_aout->p_sys->p_notif->p_events[1].dwOffset = dsbcaps.dwBufferBytes / 2;
/* Get the IDirectSoundNotify interface */
if FAILED( IDirectSoundBuffer_QueryInterface( p_aout->p_sys->p_dsbuffer,
&IID_IDirectSoundNotify,
(LPVOID *)&p_aout->p_sys->p_dsnotify ) )
{
msg_Warn( p_aout, "cannot get Notify interface" );
/* Go on anyway */
p_aout->p_sys->p_dsnotify = NULL;
return( 0 );
}
if FAILED( IDirectSoundNotify_SetNotificationPositions(
p_aout->p_sys->p_dsnotify,
2,
p_aout->p_sys->p_notif->p_events ) )
{
msg_Warn( p_aout, "cannot set position Notification" );
/* Go on anyway */
}
return( 0 );
}
/*****************************************************************************
* DirectxCreateSecondaryBuffer
*****************************************************************************
* This function destroy the secondary buffer.
*****************************************************************************/
static void DirectxDestroySecondaryBuffer( aout_thread_t *p_aout )
{
/* make sure the buffer isn't playing */
if( p_aout->p_sys->p_dsbuffer != NULL )
{
IDirectSoundBuffer_Stop( p_aout->p_sys->p_dsbuffer );
}
if( p_aout->p_sys->p_dsnotify != NULL )
{
IDirectSoundNotify_Release( p_aout->p_sys->p_dsnotify );
p_aout->p_sys->p_dsnotify = NULL;
}
if( p_aout->p_sys->p_dsbuffer != NULL )
{
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer );
p_aout->p_sys->p_dsbuffer = NULL;
}
}
/*****************************************************************************
* DirectSoundThread: this thread will capture play notification events.
*****************************************************************************
* As Direct Sound uses circular buffers, we need to use event notification to
* manage them.
* Using event notification implies blocking the thread until the event is
* signaled so we really need to run this in a separate thread.
*****************************************************************************/
static void DirectSoundThread( notification_thread_t *p_notif )
{
HANDLE notification_events[2];
VOID *p_write_position, *p_start_buffer;
long l_bytes1, l_bytes2;
HRESULT dsresult;
long l_buffer_size, l_play_position, l_data_in_buffer;
aout_thread_t *p_aout = p_notif->p_aout;
#define P_EVENTS p_aout->p_sys->p_notif->p_events
notification_events[0] = P_EVENTS[0].hEventNotify;
notification_events[1] = P_EVENTS[1].hEventNotify;
/* Tell the main thread that we are ready */
vlc_thread_ready( p_notif );
/* this thread must be high-priority */
if( !SetThreadPriority( GetCurrentThread(),
THREAD_PRIORITY_ABOVE_NORMAL ) )
{
msg_Warn( p_notif, "DirectSoundThread could not renice itself" );
}
msg_Dbg( p_notif, "DirectSoundThread ready" );
while( !p_notif->b_die )
{
/* wait for the position notification */
l_play_position = WaitForMultipleObjects( 2, notification_events,
0, INFINITE );
vlc_mutex_lock( &p_aout->p_sys->buffer_lock );
if( p_notif->b_die )
{
break;
}
/* check for buffer underflow (bodge for wrap around) */
l_buffer_size = p_aout->p_sys->l_buffer_size;
l_play_position = (l_play_position - WAIT_OBJECT_0) * l_buffer_size/2;
p_aout->p_sys->l_data_played_from_beginning += (l_buffer_size/2);
l_data_in_buffer = p_aout->p_sys->l_data_written_from_beginning -
p_aout->p_sys->l_data_played_from_beginning;
/* detect wrap-around */
if( l_data_in_buffer < (-l_buffer_size/2) )
{
msg_Dbg( p_notif, "DirectSoundThread wrap around: %li",
l_data_in_buffer );
l_data_in_buffer += l_buffer_size;
}
/* detect underflow */
if( l_data_in_buffer <= 0 )
{
msg_Warn( p_notif,
"DirectSoundThread underflow: %li", l_data_in_buffer );
p_aout->p_sys->b_buffer_underflown = 1;
p_aout->p_sys->l_write_position =
(l_play_position + l_buffer_size/2) % l_buffer_size;
l_data_in_buffer = l_buffer_size / 2;
p_aout->p_sys->l_data_played_from_beginning -= (l_buffer_size/2);
}
/* Clear the data which has already been played */
/* Before copying anything, we have to lock the buffer */
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
p_aout->p_sys->l_write_position, /* Offset of lock start */
l_buffer_size - l_data_in_buffer, /* Number of bytes */
&p_write_position, /* Address of lock start */
&l_bytes1, /* Count of bytes locked before wrap around */
&p_start_buffer, /* Buffer adress (if wrap around) */
&l_bytes2, /* Count of bytes after wrap around */
0); /* Flags */
if( dsresult == DSERR_BUFFERLOST )
{
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
p_aout->p_sys->l_write_position,
l_buffer_size - l_data_in_buffer,
&p_write_position,
&l_bytes1,
&p_start_buffer,
&l_bytes2,
0);
}
if( dsresult != DS_OK )
{
msg_Warn( p_notif, "Play cannot lock buffer" );
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return;
}
/* Now do the actual memcpy (two because the buffer is circular) */
memset( p_write_position, 0, l_bytes1 );
if( p_start_buffer != NULL )
{
memset( p_start_buffer, 0, l_bytes2 );
}
/* Now the data has been copied, unlock the buffer */
IDirectSoundBuffer_Unlock( p_aout->p_sys->p_dsbuffer,
p_write_position, l_bytes1, p_start_buffer, l_bytes2 );
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
}
/* free the events */
CloseHandle( notification_events[0] );
CloseHandle( notification_events[1] );
msg_Dbg( p_notif, "DirectSoundThread exiting" );
}

View File

@ -1,75 +0,0 @@
/*****************************************************************************
* directx.c : Windows DirectX plugin for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: directx.c,v 1.13 2002/07/31 22:37:28 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <vlc/vlc.h>
/*****************************************************************************
* External prototypes
*****************************************************************************/
int E_(OpenVideo) ( vlc_object_t * );
void E_(CloseVideo) ( vlc_object_t * );
int E_(OpenAudio) ( vlc_object_t * );
void E_(CloseAudio) ( vlc_object_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define HW_YUV_TEXT N_("use hardware YUV->RGB conversions")
#define HW_YUV_LONGTEXT N_( \
"Try to use hardware acceleration for YUV->RGB conversions. " \
"This option doesn't have any effect when using overlays." )
#define SYSMEM_TEXT N_("use video buffers in system memory")
#define SYSMEM_LONGTEXT N_( \
"Create video buffers in system memory instead of video memory. This " \
"isn't recommended as usually using video memory allows to benefit from " \
"more hardware acceleration (like rescaling or YUV->RGB conversions). " \
"This option doesn't have any effect when using overlays." )
vlc_module_begin();
add_category_hint( N_("Video"), NULL );
add_bool( "directx-hw-yuv", 1, NULL, HW_YUV_TEXT, HW_YUV_LONGTEXT );
add_bool( "directx-use-sysmem", 0, NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT );
set_description( _("DirectX extension module") );
add_submodule();
set_capability( "video output", 150 );
set_callbacks( E_(OpenVideo), E_(CloseVideo) );
add_submodule();
set_capability( "audio output", 150 );
set_callbacks( E_(OpenAudio), E_(CloseAudio) );
vlc_module_end();
#if 0 /* FIXME */
/* check if we registered a window class because we need to
* unregister it */
WNDCLASS wndclass;
if( GetClassInfo( GetModuleHandle(NULL), "VLC DirectX", &wndclass ) )
UnregisterClass( "VLC DirectX", GetModuleHandle(NULL) );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,112 +0,0 @@
/*****************************************************************************
* vout_directx.h: Windows DirectX video output header file
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vout_directx.h,v 1.11 2002/07/30 17:14:33 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* event_thread_t: DirectX event thread
*****************************************************************************/
typedef struct event_thread_t
{
VLC_COMMON_MEMBERS
vout_thread_t * p_vout;
} event_thread_t;
/*****************************************************************************
* vout_sys_t: video output DirectX method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the DirectX specific properties of an output thread.
*****************************************************************************/
struct vout_sys_t
{
LPDIRECTDRAW2 p_ddobject; /* DirectDraw object */
LPDIRECTDRAWSURFACE2 p_display; /* Display device */
LPDIRECTDRAWSURFACE2 p_current_surface; /* surface currently displayed */
LPDIRECTDRAWCLIPPER p_clipper; /* clipper used for blitting */
HINSTANCE hddraw_dll; /* handle of the opened ddraw dll */
HBRUSH hbrush; /* window backgound brush (color) */
HWND hwnd; /* Handle of the main window */
vlc_bool_t b_using_overlay; /* Are we using an overlay surface */
vlc_bool_t b_use_sysmem; /* Should we use system memory for surfaces */
vlc_bool_t b_hw_yuv; /* Should we use hardware YUV->RGB conversions */
/* size of the display */
RECT rect_display;
int i_display_depth;
/* Window position and size */
int i_window_x;
int i_window_y;
int i_window_width;
int i_window_height;
/* Coordinates of src and dest images (used when blitting to display) */
RECT rect_src;
RECT rect_src_clipped;
RECT rect_dest;
RECT rect_dest_clipped;
/* DDraw capabilities */
int b_caps_overlay_clipping;
int i_rgb_colorkey; /* colorkey in RGB used by the overlay */
int i_colorkey; /* colorkey used by the overlay */
volatile u16 i_changes; /* changes made to the video display */
/* Mouse */
volatile vlc_bool_t b_cursor_hidden;
volatile mtime_t i_lastmoved;
event_thread_t * p_event;
};
/*****************************************************************************
* picture_sys_t: direct buffer method descriptor
*****************************************************************************
* This structure is part of the picture descriptor, it describes the
* DirectX specific properties of a direct buffer.
*****************************************************************************/
struct picture_sys_t
{
LPDIRECTDRAWSURFACE2 p_surface;
DDSURFACEDESC ddsd;
LPDIRECTDRAWSURFACE2 p_front_surface;
};
/*****************************************************************************
* Prototypes from vout_directx.c
*****************************************************************************/
/*****************************************************************************
* Prototypes from vout_events.c
*****************************************************************************/
void DirectXEventThread ( event_thread_t *p_event );
void DirectXUpdateOverlay( vout_thread_t *p_vout );
/*****************************************************************************
* Constants
*****************************************************************************/
#define WM_VLC_HIDE_MOUSE WM_APP

View File

@ -1,580 +0,0 @@
/*****************************************************************************
* vout_events.c: Windows DirectX video output events handler
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: vout_events.c,v 1.25 2002/07/30 17:14:33 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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: This file contains the functions related to the creation of
* a window and the handling of its messages (events).
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include "netutils.h"
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <ddraw.h>
#include "vout_directx.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int DirectXCreateWindow( vout_thread_t *p_vout );
static void DirectXCloseWindow ( vout_thread_t *p_vout );
static void DirectXUpdateRects( vout_thread_t *p_vout );
static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam );
/*****************************************************************************
* DirectXEventThread: Create video window & handle its messages
*****************************************************************************
* This function creates a video window and then enters an infinite loop
* that handles the messages sent to that window.
* The main goal of this thread is to isolate the Win32 PeekMessage function
* because this one can block for a long time.
*****************************************************************************/
void DirectXEventThread( event_thread_t *p_event )
{
MSG msg;
POINT old_mouse_pos;
/* Initialisation */
/* Create a window for the video */
/* Creating a window under Windows also initializes the thread's event
* message qeue */
if( DirectXCreateWindow( p_event->p_vout ) )
{
msg_Err( p_event, "out of memory" );
p_event->b_dead = 1;
}
/* signal the creation of the window */
vlc_thread_ready( p_event );
/* Main loop */
/* GetMessage will sleep if there's no message in the queue */
while( !p_event->b_die
&& GetMessage( &msg, p_event->p_vout->p_sys->hwnd, 0, 0 ) )
{
/* Check if we are asked to exit */
if( p_event->b_die )
break;
switch( msg.message )
{
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE:
if( (abs(GET_X_LPARAM(msg.lParam) - old_mouse_pos.x) > 2 ||
(abs(GET_Y_LPARAM(msg.lParam) - old_mouse_pos.y)) > 2 ) )
{
GetCursorPos( &old_mouse_pos );
p_event->p_vout->p_sys->i_lastmoved = mdate();
if( p_event->p_vout->p_sys->b_cursor_hidden )
{
p_event->p_vout->p_sys->b_cursor_hidden = 0;
ShowCursor( TRUE );
}
}
break;
case WM_VLC_HIDE_MOUSE:
GetCursorPos( &old_mouse_pos );
ShowCursor( FALSE );
break;
case WM_RBUTTONUP:
{
intf_thread_t *p_intf;
p_intf = vlc_object_find( p_event, VLC_OBJECT_INTF,
FIND_ANYWHERE );
if( p_intf )
{
p_intf->b_menu_change = 1;
vlc_object_release( p_intf );
}
}
break;
case WM_LBUTTONDOWN:
break;
case WM_LBUTTONDBLCLK:
p_event->p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
break;
case WM_KEYDOWN:
/* the key events are first processed here. The next
* message processed by this main message loop will be the
* char translation of the key event */
msg_Dbg( p_event, "WM_KEYDOWN" );
switch( msg.wParam )
{
case VK_ESCAPE:
/* exit application */
p_event->p_vlc->b_die = 1;
break;
case VK_F1: network_ChannelJoin( p_event, 1 ); break;
case VK_F2: network_ChannelJoin( p_event, 2 ); break;
case VK_F3: network_ChannelJoin( p_event, 3 ); break;
case VK_F4: network_ChannelJoin( p_event, 4 ); break;
case VK_F5: network_ChannelJoin( p_event, 5 ); break;
case VK_F6: network_ChannelJoin( p_event, 6 ); break;
case VK_F7: network_ChannelJoin( p_event, 7 ); break;
case VK_F8: network_ChannelJoin( p_event, 8 ); break;
case VK_F9: network_ChannelJoin( p_event, 9 ); break;
case VK_F10: network_ChannelJoin( p_event, 10 ); break;
case VK_F11: network_ChannelJoin( p_event, 11 ); break;
case VK_F12: network_ChannelJoin( p_event, 12 ); break;
}
TranslateMessage(&msg);
break;
case WM_CHAR:
switch( msg.wParam )
{
case 'q':
case 'Q':
/* exit application */
p_event->p_vlc->b_die = 1;
break;
case 'f': /* switch to fullscreen */
case 'F':
p_event->p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
break;
case 'c': /* toggle grayscale */
case 'C':
p_event->p_vout->b_grayscale = ! p_event->p_vout->b_grayscale;
p_event->p_vout->p_sys->i_changes |= VOUT_GRAYSCALE_CHANGE;
break;
case 'i': /* toggle info */
case 'I':
p_event->p_vout->b_info = ! p_event->p_vout->b_info;
p_event->p_vout->p_sys->i_changes |= VOUT_INFO_CHANGE;
break;
case 's': /* toggle scaling */
case 'S':
p_event->p_vout->b_scale = ! p_event->p_vout->b_scale;
p_event->p_vout->p_sys->i_changes |= VOUT_SCALE_CHANGE;
break;
case ' ': /* toggle interface */
p_event->p_vout->b_interface = ! p_event->p_vout->b_interface;
p_event->p_vout->p_sys->i_changes |= VOUT_INTF_CHANGE;
break;
default:
break;
}
default:
/* Messages we don't handle directly are dispatched to the
* window procedure */
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
} /* End Switch */
} /* End Main loop */
if( msg.message == WM_QUIT )
{
msg_Warn( p_event, "WM_QUIT... should not happen!!" );
p_event->p_vout->p_sys->hwnd = NULL; /* Window already destroyed */
}
msg_Dbg( p_event, "DirectXEventThread Terminating" );
/* clear the changes formerly signaled */
p_event->p_vout->p_sys->i_changes = 0;
DirectXCloseWindow( p_event->p_vout );
}
/* following functions are local */
/*****************************************************************************
* DirectXCreateWindow: create a window for the video.
*****************************************************************************
* Before creating a direct draw surface, we need to create a window in which
* the video will be displayed. This window will also allow us to capture the
* events.
*****************************************************************************/
static int DirectXCreateWindow( vout_thread_t *p_vout )
{
HINSTANCE hInstance;
WNDCLASSEX wc; /* window class components */
RECT rect_window;
COLORREF colorkey;
HDC hdc;
HICON vlc_icon = NULL;
char vlc_path[_MAX_PATH+1];
msg_Dbg( p_vout, "DirectXCreateWindow" );
/* get this module's instance */
hInstance = GetModuleHandle(NULL);
/* Create a BRUSH that will be used by Windows to paint the window
* background.
* This window background is important for us as it will be used by the
* graphics card to display the overlay.
* This is why we carefully choose the color for this background, the goal
* being to choose a color which isn't complete black but nearly. We
* obviously don't want to use black as a colorkey for the overlay because
* black is one of the most used color and thus would give us undesirable
* effects */
/* the first step is to find the colorkey we want to use. The difficulty
* comes from the potential dithering (depends on the display depth)
* because we need to know the real RGB value of the chosen colorkey */
hdc = GetDC( NULL );
for( colorkey = 5; colorkey < 0xFF /*all shades of red*/; colorkey++ )
{
if( colorkey == GetNearestColor( hdc, colorkey ) )
break;
}
msg_Dbg( p_vout, "background color: %i", colorkey );
/* create the actual brush */
p_vout->p_sys->hbrush = CreateSolidBrush(colorkey);
p_vout->p_sys->i_rgb_colorkey = (int)colorkey;
/* Get the current size of the display and its colour depth */
p_vout->p_sys->rect_display.right = GetDeviceCaps( hdc, HORZRES );
p_vout->p_sys->rect_display.bottom = GetDeviceCaps( hdc, VERTRES );
p_vout->p_sys->i_display_depth = GetDeviceCaps( hdc, BITSPIXEL );
msg_Dbg( p_vout, "screen dimensions %ix%i colour depth %i",
p_vout->p_sys->rect_display.right,
p_vout->p_sys->rect_display.bottom,
p_vout->p_sys->i_display_depth );
ReleaseDC( NULL, hdc );
/* Get the Icon from the main app */
vlc_icon = NULL;
if( GetModuleFileName( NULL, vlc_path, _MAX_PATH ) )
{
vlc_icon = ExtractIcon( hInstance, vlc_path, 0 );
}
/* fill in the window class structure */
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS; /* style: dbl click */
wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */
wc.cbClsExtra = 0; /* no extra class data */
wc.cbWndExtra = 0; /* no extra window data */
wc.hInstance = hInstance; /* instance */
wc.hIcon = vlc_icon; /* load the vlc icon */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* load a default cursor */
wc.hbrBackground = p_vout->p_sys->hbrush; /* background color */
wc.lpszMenuName = NULL; /* no menu */
wc.lpszClassName = "VLC DirectX"; /* use a special class */
wc.hIconSm = vlc_icon; /* load the vlc icon */
/* register the window class */
if (!RegisterClassEx(&wc))
{
WNDCLASS wndclass;
/* free window background brush */
if( p_vout->p_sys->hbrush )
{
DeleteObject( p_vout->p_sys->hbrush );
p_vout->p_sys->hbrush = NULL;
}
if( vlc_icon )
DestroyIcon( vlc_icon );
/* Check why it failed. If it's because one already exists then fine */
if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
{
msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
return (1);
}
}
/* when you create a window you give the dimensions you wish it to have.
* Unfortunatly these dimensions will include the borders and title bar.
* We use the following function to find out the size of the window
* corresponding to the useable surface we want */
rect_window.top = 10;
rect_window.left = 10;
rect_window.right = rect_window.left + p_vout->p_sys->i_window_width;
rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
/* create the window */
p_vout->p_sys->hwnd = CreateWindow("VLC DirectX",/* name of window class */
VOUT_TITLE " (DirectX Output)", /* window title bar text */
WS_OVERLAPPEDWINDOW
| WS_SIZEBOX, /* window style */
CW_USEDEFAULT, /* default X coordinate */
0, /* default Y coordinate */
rect_window.right - rect_window.left, /* window width */
rect_window.bottom - rect_window.top, /* window height */
NULL, /* no parent window */
NULL, /* no menu in this window */
hInstance, /* handle of this program instance */
NULL); /* no additional arguments */
if (p_vout->p_sys->hwnd == NULL) {
msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" );
return (1);
}
/* store a p_vout pointer into the window local storage (for later use
* in DirectXEventProc).
* We need to use SetWindowLongPtr when it is available in mingw */
SetWindowLong( p_vout->p_sys->hwnd, GWL_USERDATA, (LONG)p_vout );
/* now display the window */
ShowWindow(p_vout->p_sys->hwnd, SW_SHOW);
return ( 0 );
}
/*****************************************************************************
* DirectXCloseWindow: close the window created by DirectXCreateWindow
*****************************************************************************
* This function returns all resources allocated by DirectXCreateWindow.
*****************************************************************************/
static void DirectXCloseWindow( vout_thread_t *p_vout )
{
msg_Dbg( p_vout, "DirectXCloseWindow" );
if( p_vout->p_sys->hwnd != NULL )
{
DestroyWindow( p_vout->p_sys->hwnd );
p_vout->p_sys->hwnd = NULL;
}
/* We don't unregister the Window Class because it could lead to race
* conditions and it will be done anyway by the system when the app will
* exit */
}
/*****************************************************************************
* DirectXUpdateRects:
*****************************************************************************
* This function is called when the window position and size is changed, and
* its job is to update the source and destination RECTs used to display the
* picture.
*****************************************************************************/
static void DirectXUpdateRects( vout_thread_t *p_vout )
{
int i_width, i_height, i_x, i_y;
#define rect_src p_vout->p_sys->rect_src
#define rect_src_clipped p_vout->p_sys->rect_src_clipped
#define rect_dest p_vout->p_sys->rect_dest
#define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
#define rect_display p_vout->p_sys->rect_display
vout_PlacePicture( p_vout, p_vout->p_sys->i_window_width,
p_vout->p_sys->i_window_height,
&i_x, &i_y, &i_width, &i_height );
/* Destination image position and dimensions */
rect_dest.left = i_x + p_vout->p_sys->i_window_x;
rect_dest.top = i_y + p_vout->p_sys->i_window_y;
rect_dest.right = rect_dest.left + i_width;
rect_dest.bottom = rect_dest.top + i_height;
/* UpdateOverlay directdraw function doesn't automatically clip to the
* display size so we need to do it otherwise it will fails */
/* Clip the destination window */
IntersectRect( &rect_dest_clipped, &rect_dest, &rect_display );
#if 0
msg_Dbg( p_vout, "DirectXUpdateRects image_dst_clipped coords:"
" %i,%i,%i,%i",
rect_dest_clipped.left, rect_dest_clipped.top,
rect_dest_clipped.right, rect_dest_clipped.bottom );
#endif
/* the 2 following lines are to fix a bug when clicking on the desktop */
if( (rect_dest_clipped.right - rect_dest_clipped.left)==0 ||
(rect_dest_clipped.bottom - rect_dest_clipped.top)==0 )
{
SetRectEmpty( &rect_src_clipped );
return;
}
/* src image dimensions */
rect_src.left = 0;
rect_src.top = 0;
rect_src.right = p_vout->render.i_width;
rect_src.bottom = p_vout->render.i_height;
/* Clip the source image */
rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) *
p_vout->render.i_width / (rect_dest.right - rect_dest.left);
rect_src_clipped.right = p_vout->render.i_width -
(rect_dest.right - rect_dest_clipped.right) * p_vout->render.i_width /
(rect_dest.right - rect_dest.left);
rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) *
p_vout->render.i_height / (rect_dest.bottom - rect_dest.top);
rect_src_clipped.bottom = p_vout->render.i_height -
(rect_dest.bottom - rect_dest_clipped.bottom) * p_vout->render.i_height /
(rect_dest.bottom - rect_dest.top);
#if 0
msg_Dbg( p_vout, "DirectXUpdateRects image_src_clipped"
" coords: %i,%i,%i,%i",
rect_src_clipped.left, rect_src_clipped.top,
rect_src_clipped.right, rect_src_clipped.bottom );
#endif
#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
#undef rect_display
}
/*****************************************************************************
* DirectXEventProc: This is the window event processing function.
*****************************************************************************
* On Windows, when you create a window you have to attach an event processing
* function to it. The aim of this function is to manage "Queued Messages" and
* "Nonqueued Messages".
* Queued Messages are those picked up and retransmitted by vout_Manage
* (using the GetMessage and DispatchMessage functions).
* Nonqueued Messages are those that Windows will send directly to this
* procedure (like WM_DESTROY, WM_WINDOWPOSCHANGED...)
*****************************************************************************/
static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
vout_thread_t *p_vout =
(vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA );
switch( message )
{
case WM_WINDOWPOSCHANGED:
{
RECT rect_window;
POINT point_window;
/* update the window position */
point_window.x = 0;
point_window.y = 0;
ClientToScreen( hwnd, &point_window );
p_vout->p_sys->i_window_x = point_window.x;
p_vout->p_sys->i_window_y = point_window.y;
/* update the window size */
GetClientRect( hwnd, &rect_window );
p_vout->p_sys->i_window_width = rect_window.right;
p_vout->p_sys->i_window_height = rect_window.bottom;
DirectXUpdateRects( p_vout );
if( p_vout->p_sys->b_using_overlay &&
!p_vout->p_sys->p_event->b_die )
DirectXUpdateOverlay( p_vout );
/* signal the size change */
if( !p_vout->p_sys->b_using_overlay &&
!p_vout->p_sys->p_event->b_die )
p_vout->p_sys->i_changes |= VOUT_SIZE_CHANGE;
return 0;
}
break;
/* the user wants to close the window */
case WM_CLOSE:
msg_Dbg( p_vout, "WinProc WM_CLOSE" );
/* exit application */
p_vout->p_vlc->b_die = 1;
return 0;
break;
/* the window has been closed so shut down everything now */
case WM_DESTROY:
msg_Dbg( p_vout, "WinProc WM_DESTROY" );
/* just destroy the window */
PostQuitMessage( 0 );
return 0;
break;
case WM_SYSCOMMAND:
switch (wParam)
{
case SC_SCREENSAVE: /* catch the screensaver */
case SC_MONITORPOWER: /* catch the monitor turn-off */
msg_Dbg( p_vout, "WinProc WM_SYSCOMMAND" );
return 0; /* this stops them from happening */
}
break;
case WM_ERASEBKGND:
if( !p_vout->p_sys->b_using_overlay )
{
/* We want to eliminate unnecessary background redraws which create
* an annoying flickering */
int i_width, i_height, i_x, i_y;
RECT rect_temp;
GetClipBox( (HDC)wParam, &rect_temp );
#if 0
msg_Dbg( p_vout, "WinProc WM_ERASEBKGND %i,%i,%i,%i",
rect_temp.left, rect_temp.top,
rect_temp.right, rect_temp.bottom );
#endif
vout_PlacePicture( p_vout, p_vout->p_sys->i_window_width,
p_vout->p_sys->i_window_height,
&i_x, &i_y, &i_width, &i_height );
ExcludeClipRect( (HDC)wParam, i_x, i_y,
i_x + i_width, i_y + i_height );
}
break;
default:
//msg_Dbg( p_vout, "WinProc WM Default %i", message );
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

View File

@ -1,3 +0,0 @@
downmix_SOURCES = downmix.c ac3_downmix_c.c
downmixsse_SOURCES = downmix.c ac3_downmix_sse.c
downmix3dn_SOURCES = downmix.c ac3_downmix_3dn.c

View File

@ -1,307 +0,0 @@
/*****************************************************************************
* ac3_downmix_3dn.c: accelerated 3D Now! ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_3dn.c,v 1.12 2002/07/31 20:56:51 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.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
*****************************************************************************/
#include <vlc/vlc.h>
#include "ac3_downmix.h"
static const float sqrt2_3dn __asm__ ("sqrt2_3dn") = 0.7071068;
void E_( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $128, %%ebx\n" /* loop counter */
"movd (%%ecx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ecx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
"movd 8(%%ecx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".align 16\n"
".loop:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"movq 3072(%%eax), %%mm3\n" /* leftsur */
"movq 4096(%%eax), %%mm4\n" /* rightsur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfadd %%mm2, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfmul %%mm7, %%mm4\n"
"pfadd %%mm3, %%mm0\n"
"pfadd %%mm4, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ebx\n"
"jnz .loop\n"
"popl %%ebx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $128, %%ebx\n" /* loop counter */
"movd (%%ecx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 8(%%ecx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".align 16\n"
".loop3:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 1024(%%eax), %%mm1\n" /* right */
"movq 2048(%%eax), %%mm3\n" /* leftsur */
"movq 3072(%%eax), %%mm4\n" /* rightsur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfmul %%mm7, %%mm4\n"
"pfadd %%mm3, %%mm0\n"
"pfadd %%mm4, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ebx\n"
"jnz .loop3\n"
"popl %%ebx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $128, %%ebx\n" /* loop counter */
"movd (%%ecx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ecx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
"movd 8(%%ecx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".align 16\n"
".loop4:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"movq 3072(%%eax), %%mm3\n" /* sur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfmul %%mm7, %%mm3\n"
"pfadd %%mm2, %%mm1\n"
"pfsub %%mm3, %%mm0\n"
"pfadd %%mm3, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ebx\n"
"jnz .loop4\n"
"popl %%ebx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $128, %%ebx\n" /* loop counter */
"movd (%%ecx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 8(%%ecx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".align 16\n"
".loop5:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 1024(%%eax), %%mm1\n" /* right */
"movq 2048(%%eax), %%mm3\n" /* sur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfsub %%mm3, %%mm0\n"
"pfadd %%mm3, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ebx\n"
"jnz .loop5\n"
"popl %%ebx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $128, %%ebx\n" /* loop counter */
"movd (%%ecx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ecx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
".align 16\n"
".loop6:\n"
"movq (%%eax), %%mm0\n" /*left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfadd %%mm2, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ebx\n"
"jnz .loop6\n"
"popl %%ebx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"pushl %%edx\n"
"movl $sqrt2_3dn, %%edx\n"
"movd (%%edx), %%mm7\n"
"punpckldq %%mm7, %%mm7\n" /* sqrt2 | sqrt2 */
"movl $128, %%ebx\n"
".align 16\n"
".loop2:\n"
"movq (%%ecx), %%mm0\n" /* c1 | c0 */
"pfmul %%mm7, %%mm0\n"
"pf2id %%mm0, %%mm0\n" /* c1 c0 --> mm0, int_32 */
"packssdw %%mm0, %%mm0\n" /* c1 c1 c0 c0 --> mm0, int_16 */
"movq %%mm0, (%%eax)\n"
"addl $8, %%eax\n"
"addl $8, %%ecx\n"
"decl %%ebx\n"
"jnz .loop2\n"
"popl %%edx\n"
"popl %%ebx\n"
"femms\n"
: "=a" (s16_samples), "=c" (left)
: "a" (s16_samples), "c" (left));
}
void E_( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $128, %%ebx\n"
".align 16\n"
".loop1:\n"
"movq (%%ecx), %%mm0\n" /* l1 | l0 */
"movq (%%edx), %%mm1\n" /* r1 | r0 */
"movq %%mm0, %%mm2\n" /* l1 | l0 */
"punpckldq %%mm1, %%mm0\n" /* r0 | l0 */
"punpckhdq %%mm1, %%mm2\n" /* r1 | l1 */
"pf2id %%mm0, %%mm0\n" /* r0 l0 --> mm0, int_32 */
"pf2id %%mm2, %%mm2\n" /* r0 l0 --> mm0, int_32 */
"packssdw %%mm2, %%mm0\n" /* r1 l1 r0 l0 --> mm0, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm2, 8(%%eax)\n"
"addl $8, %%eax\n"
"addl $8, %%ecx\n"
"addl $8, %%edx\n"
"decl %%ebx\n"
"jnz .loop1\n"
"popl %%ebx\n"
"femms\n"
: "=a" (s16_samples), "=c" (left), "=d" (right)
: "a" (s16_samples), "c" (left), "d" (right));
}

View File

@ -1,151 +0,0 @@
/*****************************************************************************
* ac3_downmix_c.c: ac3 downmix functions in C
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_c.c,v 1.6 2002/07/31 20:56:51 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
*****************************************************************************/
#include <string.h> /* memcpy() */
#include <vlc/vlc.h>
#include "ac3_downmix.h"
void E_( downmix_3f_2r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center, *left_sur, *right_sur;
float left_tmp, right_tmp;
left = samples;
center = samples + 256;
right = samples + 256*2;
left_sur = samples + 256*3;
right_sur = samples + 256*4;
for (i=0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->clev * *center + dm_par->slev * *left_sur++;
right_tmp = dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*center++ = right_tmp;
}
}
void E_( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *left_sur, *right_sur;
float left_tmp, right_tmp;
left = &samples[0];
right = &samples[256];
left_sur = &samples[512];
right_sur = &samples[768];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->slev * *left_sur++;
right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*right++ = right_tmp;
}
}
void E_( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center, *right_sur;
float left_tmp, right_tmp;
left = &samples[0];
right = &samples[512];
center = &samples[256];
right_sur = &samples[768];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->clev * *center - dm_par->slev * *right_sur;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*center++ = right_tmp;
}
}
void E_( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *right_sur;
float left_tmp, right_tmp;
left = &samples[0];
right = &samples[256];
right_sur = &samples[512];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left - dm_par->slev * *right_sur;
right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*right++ = right_tmp;
}
}
void E_( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center;
float left_tmp, right_tmp;
left = &samples[0];
center = &samples[256];
right = &samples[512];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->clev * *center;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center;
*left++ = left_tmp;
*center++ = right_tmp;
}
}
void E_( stream_sample_2ch_to_s16 ) (s16 *out_buf, float *left, float *right)
{
int i;
for (i=0; i < 256; i++) {
*out_buf++ = (s16) (*left++);
*out_buf++ = (s16) (*right++);
}
}
void E_( stream_sample_1ch_to_s16 ) (s16 *out_buf, float *center)
{
int i;
float tmp;
for (i=0; i < 256; i++) {
*out_buf++ = tmp = (s16) (0.7071f * *center++);
*out_buf++ = tmp;
}
}

View File

@ -1,32 +0,0 @@
/*****************************************************************************
* ac3_downmix_common.h: ac3 downmix functions headers
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_common.h,v 1.2 2002/07/31 20:56:51 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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.
*****************************************************************************/
void E_( downmix_3f_2r_to_2ch ) ( float *, dm_par_t * );
void E_( downmix_2f_2r_to_2ch ) ( float *, dm_par_t * );
void E_( downmix_3f_1r_to_2ch ) ( float *, dm_par_t * );
void E_( downmix_2f_1r_to_2ch ) ( float *, dm_par_t * );
void E_( downmix_3f_0r_to_2ch ) ( float *, dm_par_t * );
void E_( stream_sample_2ch_to_s16 ) ( s16 *, float *, float * );
void E_( stream_sample_1ch_to_s16 ) ( s16 *, float * );

View File

@ -1,312 +0,0 @@
/*****************************************************************************
* ac3_downmix_sse.c: accelerated SSE ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_sse.c,v 1.12 2002/07/31 20:56:51 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
*****************************************************************************/
#include <vlc/vlc.h>
#include "ac3_downmix.h"
static const float sqrt2_sse __asm__ ("sqrt2_sse") __attribute__ ((aligned (16))) = 0.7071068;
void E_( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $64, %%ebx\n" /* loop counter */
"movss (%%ecx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 4(%%ecx), %%xmm6\n" /* clev */
"shufps $0, %%xmm6, %%xmm6\n" /* clev | clev | clev | clev */
"movss 8(%%ecx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".align 16\n"
".loop:\n"
"movaps (%%eax), %%xmm0\n" /* left */
"movaps 2048(%%eax), %%xmm1\n" /* right */
"movaps 1024(%%eax), %%xmm2\n" /* center */
"movaps 3072(%%eax), %%xmm3\n" /* leftsur */
"movaps 4096(%%eax), %%xmm4\n" /* rithgsur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm6, %%xmm2\n"
"addps %%xmm2, %%xmm0\n"
"addps %%xmm2, %%xmm1\n"
"mulps %%xmm7, %%xmm3\n"
"mulps %%xmm7, %%xmm4\n"
"addps %%xmm3, %%xmm0\n"
"addps %%xmm4, %%xmm1\n"
"movaps %%xmm0, (%%eax)\n"
"movaps %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ebx\n"
"jnz .loop\n"
"popl %%ebx\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $64, %%ebx\n" /* loop counter */
"movss (%%ecx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 8(%%ecx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".align 16\n"
".loop3:\n"
"movaps (%%eax), %%xmm0\n" /* left */
"movaps 1024(%%eax), %%xmm1\n" /* right */
"movaps 2048(%%eax), %%xmm3\n" /* leftsur */
"movaps 3072(%%eax), %%xmm4\n" /* rightsur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm7, %%xmm3\n"
"mulps %%xmm7, %%xmm4\n"
"addps %%xmm3, %%xmm0\n"
"addps %%xmm4, %%xmm1\n"
"movaps %%xmm0, (%%eax)\n"
"movaps %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ebx\n"
"jnz .loop3\n"
"popl %%ebx\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $64, %%ebx\n" /* loop counter */
"movss (%%ecx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 4(%%ecx), %%xmm6\n" /* clev */
"shufps $0, %%xmm6, %%xmm6\n" /* clev | clev | clev | clev */
"movss 8(%%ecx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".align 16\n"
".loop4:\n"
"movaps (%%eax), %%xmm0\n" /* left */
"movaps 2048(%%eax), %%xmm1\n" /* right */
"movaps 1024(%%eax), %%xmm2\n" /* center */
"movaps 3072(%%eax), %%xmm3\n" /* sur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm6, %%xmm2\n"
"addps %%xmm2, %%xmm0\n"
"mulps %%xmm7, %%xmm3\n"
"addps %%xmm2, %%xmm1\n"
"subps %%xmm3, %%xmm0\n"
"addps %%xmm3, %%xmm1\n"
"movaps %%xmm0, (%%eax)\n"
"movaps %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ebx\n"
"jnz .loop4\n"
"popl %%ebx\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $64, %%ebx\n" /* loop counter */
"movss (%%ecx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 8(%%ecx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".align 16\n"
".loop5:\n"
"movaps (%%eax), %%xmm0\n" /* left */
"movaps 1024(%%eax), %%xmm1\n" /* right */
"movaps 2048(%%eax), %%xmm3\n" /* sur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm7, %%xmm3\n"
"subps %%xmm3, %%xmm0\n"
"addps %%xmm3, %%xmm1\n"
"movaps %%xmm0, (%%eax)\n"
"movaps %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ebx\n"
"jnz .loop5\n"
"popl %%ebx\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $64, %%ebx\n" /* loop counter */
"movss (%%ecx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 4(%%ecx), %%xmm6\n" /* clev */
"shufps $0, %%xmm6, %%xmm6\n" /* clev | clev | clev | clev */
".align 16\n"
".loop6:\n"
"movaps (%%eax), %%xmm0\n" /*left */
"movaps 2048(%%eax), %%xmm1\n" /* right */
"movaps 1024(%%eax), %%xmm2\n" /* center */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm6, %%xmm2\n"
"addps %%xmm2, %%xmm0\n"
"addps %%xmm2, %%xmm1\n"
"movaps %%xmm0, (%%eax)\n"
"movaps %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ebx\n"
"jnz .loop6\n"
"popl %%ebx\n"
: "=a" (samples)
: "a" (samples), "c" (dm_par));
}
void E_( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"pushl %%edx\n"
"movl $sqrt2_sse, %%edx\n"
"movss (%%edx), %%xmm7\n"
"shufps $0, %%xmm7, %%xmm7\n" /* sqrt2 | sqrt2 | sqrt2 | sqrt2 */
"movl $64, %%ebx\n"
".align 16\n"
".loop2:\n"
"movaps (%%ecx), %%xmm0\n" /* c3 | c2 | c1 | c0 */
"mulps %%xmm7, %%xmm0\n"
"movhlps %%xmm0, %%xmm2\n" /* c3 | c2 */
"cvtps2pi %%xmm0, %%mm0\n" /* c1 c0 --> mm0, int_32 */
"cvtps2pi %%xmm2, %%mm1\n" /* c3 c2 --> mm1, int_32 */
"packssdw %%mm0, %%mm0\n" /* c1 c1 c0 c0 --> mm0, int_16 */
"packssdw %%mm1, %%mm1\n" /* c3 c3 c2 c2 --> mm1, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 8(%%eax)\n"
"addl $16, %%eax\n"
"addl $16, %%ecx\n"
"decl %%ebx\n"
"jnz .loop2\n"
"popl %%edx\n"
"popl %%ebx\n"
"emms\n"
: "=a" (s16_samples), "=c" (left)
: "a" (s16_samples), "c" (left));
}
void E_( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
{
__asm__ __volatile__ (
".align 16\n"
"pushl %%ebx\n"
"movl $64, %%ebx\n"
".align 16\n"
".loop1:\n"
"movaps (%%ecx), %%xmm0\n" /* l3 | l2 | l1 | l0 */
"movaps (%%edx), %%xmm1\n" /* r3 | r2 | r1 | r0 */
"movhlps %%xmm0, %%xmm2\n" /* l3 | l2 */
"movhlps %%xmm1, %%xmm3\n" /* r3 | r2 */
"unpcklps %%xmm1, %%xmm0\n" /* r1 | l1 | r0 | l0 */
"unpcklps %%xmm3, %%xmm2\n" /* r3 | l3 | r2 | l2 */
"cvtps2pi %%xmm0, %%mm0\n" /* r0 l0 --> mm0, int_32 */
"movhlps %%xmm0, %%xmm0\n"
"cvtps2pi %%xmm0, %%mm1\n" /* r1 l1 --> mm1, int_32 */
"cvtps2pi %%xmm2, %%mm2\n" /* r2 l2 --> mm2, int_32 */
"movhlps %%xmm2, %%xmm2\n"
"cvtps2pi %%xmm2, %%mm3\n" /* r3 l3 --> mm3, int_32 */
"packssdw %%mm1, %%mm0\n" /* r1 l1 r0 l0 --> mm0, int_16 */
"packssdw %%mm3, %%mm2\n" /* r3 l3 r2 l2 --> mm2, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm2, 8(%%eax)\n"
"addl $16, %%eax\n"
"addl $16, %%ecx\n"
"addl $16, %%edx\n"
"decl %%ebx\n"
"jnz .loop1\n"
"popl %%ebx\n"
"emms\n"
: "=a" (s16_samples), "=c" (left), "=d" (right)
: "a" (s16_samples), "c" (left), "d" (right));
}

View File

@ -1,73 +0,0 @@
/*****************************************************************************
* downmix.c : AC3 downmix module
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: downmix.c,v 1.10 2002/07/31 20:56:51 sam Exp $
*
* Authors: Renaud Dartus <reno@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
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include "ac3_downmix.h"
#include "ac3_downmix_common.h"
/*****************************************************************************
* Module initializer
*****************************************************************************/
static int Open ( vlc_object_t *p_this )
{
downmix_t *p_downmix = (downmix_t *)p_this;
p_downmix->pf_downmix_3f_2r_to_2ch = E_( downmix_3f_2r_to_2ch );
p_downmix->pf_downmix_3f_1r_to_2ch = E_( downmix_3f_1r_to_2ch );
p_downmix->pf_downmix_2f_2r_to_2ch = E_( downmix_2f_2r_to_2ch );
p_downmix->pf_downmix_2f_1r_to_2ch = E_( downmix_2f_1r_to_2ch );
p_downmix->pf_downmix_3f_0r_to_2ch = E_( downmix_3f_0r_to_2ch );
p_downmix->pf_stream_sample_2ch_to_s16 = E_( stream_sample_2ch_to_s16 );
p_downmix->pf_stream_sample_1ch_to_s16 = E_( stream_sample_1ch_to_s16 );
return VLC_SUCCESS;
}
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
#ifdef MODULE_NAME_IS_downmix
set_description( _("AC3 downmix module") );
set_capability( "downmix", 50 );
add_shortcut( "c" );
#elif defined( MODULE_NAME_IS_downmixsse )
set_description( _("SSE AC3 downmix module") );
set_capability( "downmix", 200 );
add_shortcut( "sse" );
#elif defined( MODULE_NAME_IS_downmix3dn )
set_description( _("3D Now! AC3 downmix module") );
set_capability( "downmix", 200 );
add_shortcut( "3dn" );
add_shortcut( "3dnow" );
#endif
set_callbacks( Open, NULL );
vlc_module_end();

View File

@ -1,4 +0,0 @@
.dep
*.lo
*.o.*
*.lo.*

Some files were not shown because too many files have changed in this diff Show More