(There are still a few decoders/packetizers left to be converted but this shouldn't take too long).
* ALL: small improvements to the encoders api.
* aout_internal.h : internal defines for audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: aout_internal.h,v 1.41 2003/10/27 21:54:10 gbazin Exp $
+ * $Id: aout_internal.h,v 1.42 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
/*****************************************************************************
* aout_filter_t : audio output filter
*****************************************************************************/
-typedef struct aout_filter_t
+struct aout_filter_t
{
VLC_COMMON_MEMBERS
struct aout_buffer_t * );
vlc_bool_t b_in_place;
vlc_bool_t b_continuity;
-} aout_filter_t;
+};
/*****************************************************************************
* aout_mixer_t : audio output mixer
aout_buffer_t * p_buffer );
/* From filters.c : */
-int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
- aout_filter_t ** pp_filters,
- int * pi_nb_filters,
- const audio_sample_format_t * p_input_format,
- const audio_sample_format_t * p_output_format );
-void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
- aout_filter_t ** pp_filters,
- int i_nb_filters );
-void aout_FiltersHintBuffers( aout_instance_t * p_aout,
- aout_filter_t ** pp_filters,
- int i_nb_filters, aout_alloc_t * p_first_alloc );
-void aout_FiltersPlay( aout_instance_t * p_aout,
- aout_filter_t ** pp_filters,
- int i_nb_filters, aout_buffer_t ** pp_input_buffer );
+VLC_EXPORT( int, aout_FiltersCreatePipeline, ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) );
+VLC_EXPORT( void, aout_FiltersDestroyPipeline, ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters ) );
+VLC_EXPORT( void, aout_FiltersPlay, ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters, aout_buffer_t ** pp_input_buffer ) );
+void aout_FiltersHintBuffers( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters, aout_alloc_t * p_first_alloc );
/* From mixer.c : */
int aout_MixerNew( aout_instance_t * p_aout );
* audio_output.h : audio output interface
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: audio_output.h,v 1.83 2003/10/08 21:01:07 gbazin Exp $
+ * $Id: audio_output.h,v 1.84 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*****************************************************************************
* This structure defines a format for audio samples.
*****************************************************************************/
-struct audio_sample_format_t
+struct audio_format_t
{
vlc_fourcc_t i_format;
+
unsigned int i_rate;
+
/* Describes the channels configuration of the samples (ie. number of
* channels which are available in the buffer, and positions). */
uint32_t i_physical_channels;
+
/* Describes from which original channels, before downmixing, the
* buffer is derived. */
uint32_t i_original_channels;
+
/* Optional - for A/52, SPDIF and DTS types : */
/* Bytes used by one compressed frame, depends on bitrate. */
unsigned int i_bytes_per_frame;
+
/* Number of sampleframes contained in one compressed frame. */
unsigned int i_frame_length;
/* Please note that it may be completely arbitrary - buffers are not
* just here for the division :
* buffer_size = i_nb_samples * i_bytes_per_frame / i_frame_length
*/
+
+ /* FIXME ? (used by the codecs) */
+ int i_bitrate;
+ int i_channels;
+ int i_blockalign;
+ int i_bitspersample;
};
#define AOUT_FMTS_IDENTICAL( p_first, p_second ) ( \
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.97 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: input_ext-intf.h,v 1.98 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
#ifndef _VLC_INPUT_EXT_INTF_H
#define _VLC_INPUT_EXT_INTF_H 1
+#include "ninput.h"
+
/*
* Communication input -> interface
*/
unsigned int i_pes_real_size; /* as indicated by the header */
/* Decoder information */
+ es_format_t fmt;
decoder_fifo_t * p_decoder_fifo;
void * p_waveformatex;
void * p_bitmapinfoheader;
* ninput.h
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ninput.h,v 1.14 2003/11/13 17:59:34 gbazin Exp $
+ * $Id: ninput.h,v 1.15 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
#ifndef _NINPUT_H
#define _NINPUT_H 1
+#include "audio_output.h"
+#include "vlc_video.h"
+
enum es_extra_type_e
{
ES_EXTRA_TYPE_UNKNOWN,
ES_EXTRA_TYPE_SUBHEADER
};
+typedef struct subs_format_t
+{
+ char *psz_encoding;
+
+} subs_format_t;
+
typedef struct
{
int i_cat;
char *psz_language;
char *psz_description;
- struct
- {
- int i_samplerate;
- int i_channels;
- int i_bitrate;
- int i_blockalign;
- int i_bitspersample;
- } audio;
-
- struct
- {
- int i_width;
- int i_height;
- int i_display_width;
- int i_display_height;
- } video;
-
- struct
- {
- char *psz_encoding;
- } subs;
+ audio_format_t audio;
+ video_format_t video;
+ subs_format_t subs;
+
+ int i_bitrate;
int i_extra_type;
int i_extra;
void *p_extra;
+
} es_format_t;
static inline void es_format_Init( es_format_t *fmt,
fmt->psz_language = NULL;
fmt->psz_description = NULL;
- fmt->audio.i_samplerate = 0;
- fmt->audio.i_channels = 0;
- fmt->audio.i_bitrate = 0;
- fmt->audio.i_blockalign = 0;
- fmt->audio.i_bitspersample = 0;
-
- fmt->video.i_width = 0;
- fmt->video.i_height = 0;
- fmt->video.i_display_width = 0;
- fmt->video.i_display_height = 0;
-
- fmt->subs.psz_encoding = NULL;
+ memset( &fmt->audio, 0, sizeof(audio_format_t) );
+ memset( &fmt->video, 0, sizeof(video_format_t) );
+ memset( &fmt->subs, 0, sizeof(subs_format_t) );
fmt->i_extra_type = ES_EXTRA_TYPE_UNKNOWN;
fmt->i_extra = 0;
* vlc_block_helper.h: Helper functions for data blocks management.
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: vlc_block_helper.h,v 1.4 2003/10/23 20:51:20 gbazin Exp $
+ * $Id: vlc_block_helper.h,v 1.5 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
block_t *p_chain;
block_t *p_block;
int i_offset;
+
} block_bytestream_t;
-#define block_BytestreamInit( a, b, c ) __block_BytestreamInit( VLC_OBJECT(a), b, c )
+#define block_BytestreamInit( a ) __block_BytestreamInit( VLC_OBJECT(a) )
/*****************************************************************************
* block_bytestream_t management
*****************************************************************************/
-static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj,
- block_t *p_block, int i_offset )
+static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj )
{
block_bytestream_t bytestream;
- bytestream.i_offset = i_offset;
- bytestream.p_block = p_block;
- bytestream.p_chain = p_block;
+ bytestream.i_offset = 0;
+ bytestream.p_chain = bytestream.p_block = NULL;
return bytestream;
}
-static inline block_t *block_BytestreamFlush( block_bytestream_t *p_bytestream)
+static inline void block_BytestreamRelease( block_bytestream_t *p_bytestream )
+{
+ while( p_bytestream->p_chain )
+ {
+ block_t *p_next;
+ p_next = p_bytestream->p_chain->p_next;
+ p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
+ p_bytestream->p_chain = p_next;
+ }
+ p_bytestream->i_offset = 0;
+ p_bytestream->p_chain = p_bytestream->p_block = NULL;
+}
+
+static inline void block_BytestreamFlush( block_bytestream_t *p_bytestream )
{
while( p_bytestream->p_chain != p_bytestream->p_block )
{
p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
p_bytestream->p_chain = p_next;
}
+ while( p_bytestream->p_block &&
+ (p_bytestream->p_block->i_buffer - p_bytestream->i_offset) == 0 )
+ {
+ block_t *p_next;
+ p_next = p_bytestream->p_chain->p_next;
+ p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
+ p_bytestream->p_chain = p_bytestream->p_block = p_next;
+ p_bytestream->i_offset = 0;
+ }
+}
- return p_bytestream->p_chain;
+static inline void block_BytestreamPush( block_bytestream_t *p_bytestream,
+ block_t *p_block )
+{
+ block_ChainAppend( &p_bytestream->p_chain, p_block );
+ if( !p_bytestream->p_block ) p_bytestream->p_block = p_block;
+}
+
+static inline block_t *block_BytestreamPop( block_bytestream_t *p_bytestream )
+{
+ block_t *p_block;
+
+ block_BytestreamFlush( p_bytestream );
+
+ p_block = p_bytestream->p_block;
+ if( p_block == NULL )
+ {
+ return NULL;
+ }
+ else if( !p_block->p_next )
+ {
+ p_block->p_buffer += p_bytestream->i_offset;
+ p_block->i_buffer -= p_bytestream->i_offset;
+ p_bytestream->i_offset = 0;
+ p_bytestream->p_chain = p_bytestream->p_block = NULL;
+ return p_block;
+ }
+
+ while( p_block->p_next && p_block->p_next->p_next )
+ p_block = p_block->p_next;
+
+ {
+ block_t *p_block_old = p_block;
+ p_block = p_block->p_next;
+ p_block_old->p_next = NULL;
+ }
+
+ return p_block;
}
static inline int block_SkipByte( block_bytestream_t *p_bytestream )
return VLC_EGENERIC;
}
+static inline int block_WaitBytes( block_bytestream_t *p_bytestream,
+ int i_data )
+{
+ block_t *p_block;
+ int i_offset, i_copy, i_size;
+
+ /* Check we have that much data */
+ i_offset = p_bytestream->i_offset;
+ i_size = i_data;
+ i_copy = 0;
+ for( p_block = p_bytestream->p_block;
+ p_block != NULL; p_block = p_block->p_next )
+ {
+ i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
+ i_size -= i_copy;
+ i_offset = 0;
+
+ if( !i_size ) break;
+ }
+
+ if( i_size )
+ {
+ /* Not enough data, bail out */
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
static inline int block_SkipBytes( block_bytestream_t *p_bytestream,
int i_data )
{
* vlc_codec.h: codec related structures
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
- * $Id: vlc_codec.h,v 1.3 2003/11/05 18:59:01 gbazin Exp $
+ * $Id: vlc_codec.h,v 1.4 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
#ifndef _VLC_CODEC_H
#define _VLC_CODEC_H 1
+#include "ninput.h"
+
/**
* \file
* This file defines the structure and types used by decoders and encoders
*/
+typedef struct decoder_owner_sys_t decoder_owner_sys_t;
+
/**
* \defgroup decoder Decoder
*
/* Module properties */
module_t * p_module;
decoder_sys_t * p_sys;
- int ( * pf_init ) ( decoder_t * );
+
+ /* Deprecated */
int ( * pf_decode )( decoder_t *, block_t * );
- int ( * pf_end ) ( decoder_t * );
+ decoder_fifo_t * p_fifo;
+ int ( * pf_run ) ( decoder_fifo_t * );
+ /* End deprecated */
- /* Input properties */
- decoder_fifo_t * p_fifo; /* stores the PES stream data */
+ picture_t * ( * pf_decode_video )( decoder_t *, block_t ** );
+ aout_buffer_t * ( * pf_decode_audio )( decoder_t *, block_t ** );
+ void ( * pf_decode_sub) ( decoder_t *, block_t ** );
+ block_t * ( * pf_packetize ) ( decoder_t *, block_t ** );
- /* Tmp field for old decoder api */
- int ( * pf_run ) ( decoder_fifo_t * );
+ /* Input format ie from demuxer (XXX: a lot of field could be invalid) */
+ es_format_t fmt_in;
+
+ /* Output format of decoder/packetizer */
+ es_format_t fmt_out;
+
+ /*
+ * Buffers allocation
+ */
+
+ /* Audio output callbacks */
+ aout_buffer_t * ( * pf_aout_buffer_new) ( decoder_t *, int );
+ void ( * pf_aout_buffer_del) ( decoder_t *, aout_buffer_t * );
+
+ /* Video output callbacks */
+ picture_t * ( * pf_vout_buffer_new) ( decoder_t * );
+ void ( * pf_vout_buffer_del) ( decoder_t *, picture_t * );
+
+
+ /* Private structure for the owner of the decoder */
+ decoder_owner_sys_t *p_owner;
};
/**
block_t * ( * pf_encode_audio )( encoder_t *, aout_buffer_t * );
/* Properties of the input data fed to the encoder */
- union {
- audio_sample_format_t audio;
- video_frame_format_t video;
- } format;
+ es_format_t fmt_in;
/* Properties of the output of the encoder */
- vlc_fourcc_t i_fourcc;
- int i_bitrate;
-
- int i_extra_data;
- uint8_t *p_extra_data;
+ es_format_t fmt_out;
/* FIXME: move these to the ffmpeg encoder */
- int i_frame_rate;
- int i_frame_rate_base;
- int i_aspect;
int i_key_int;
int i_b_frames;
int i_vtolerance;
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.85 2003/10/29 17:32:54 zorglub Exp $
+ * $Id: vlc_common.h,v 1.86 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
typedef struct aout_fifo_t aout_fifo_t;
typedef struct aout_input_t aout_input_t;
typedef struct aout_buffer_t aout_buffer_t;
-typedef struct audio_sample_format_t audio_sample_format_t;
+typedef struct audio_format_t audio_format_t;
+typedef audio_format_t audio_sample_format_t;
typedef struct audio_date_t audio_date_t;
+typedef struct aout_filter_t aout_filter_t;
/* Video */
typedef struct vout_thread_t vout_thread_t;
typedef struct vout_sys_t vout_sys_t;
typedef struct chroma_sys_t chroma_sys_t;
-typedef struct video_frame_format_t video_frame_format_t;
+typedef struct video_format_t video_format_t;
+typedef video_format_t video_frame_format_t;
typedef struct picture_t picture_t;
typedef struct picture_sys_t picture_sys_t;
typedef struct picture_heap_t picture_heap_t;
* includes all common video types and constants.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vlc_video.h,v 1.5 2003/10/24 21:27:06 gbazin Exp $
+ * $Id: vlc_video.h,v 1.6 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
/**
* Description of a video frame
*/
-struct video_frame_format_t
+struct video_format_t
{
vlc_fourcc_t i_chroma; /**< picture chroma */
unsigned int i_aspect; /**< aspect ratio */
unsigned int i_bits_per_pixel; /**< number of bits per pixel */
+ unsigned int i_frame_rate; /**< frame rate numerator */
+ unsigned int i_frame_rate_base; /**< frame rate denominator */
};
/**
/*****************************************************************************
- * a52.c: A/52 basic parser
+ * a52.c: parse A/52 audio sync info and packetize the stream
*****************************************************************************
* Copyright (C) 2001-2002 VideoLAN
- * $Id: a52.c,v 1.28 2003/10/23 20:51:20 gbazin Exp $
+ * $Id: a52.c,v 1.29 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* memcpy() */
-#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#include <vlc/aout.h>
-#include <vlc/sout.h>
#include "vlc_block_helper.h"
/*
* Input properties
*/
- int i_state;
+ int i_state;
- block_t *p_chain;
block_bytestream_t bytestream;
- /*
- * Decoder output properties
- */
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
- audio_sample_format_t aout_format;
- aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
- sout_buffer_t * p_sout_buffer; /* current sout buffer */
-
/*
* Common properties
*/
- uint8_t *p_out_buffer; /* output buffer */
- audio_date_t end_date;
+ audio_date_t end_date;
- mtime_t pts;
+ mtime_t i_pts;
int i_frame_size, i_bit_rate;
unsigned int i_rate, i_channels, i_channels_conf;
STATE_NOSYNC,
STATE_SYNC,
STATE_HEADER,
- STATE_DATA
+ STATE_NEXT_SYNC,
+ STATE_GET_DATA,
+ STATE_SEND_DATA
};
/****************************************************************************
****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int OpenPacketizer( vlc_object_t * );
-
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void CloseDecoder ( vlc_object_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
static int SyncInfo ( const byte_t *, int *, int *, int *,int * );
-static int GetOutBuffer ( decoder_t *, uint8_t ** );
-static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
-static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
-static int SendOutBuffer( decoder_t * );
+static uint8_t *GetOutBuffer ( decoder_t *, void ** );
+static aout_buffer_t *GetAoutBuffer( decoder_t * );
+static block_t *GetSoutBuffer( decoder_t * );
/*****************************************************************************
* Module descriptor
vlc_module_begin();
set_description( _("A/52 parser") );
set_capability( "decoder", 100 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_submodule();
set_description( _("A/52 audio packetizer") );
set_capability( "packetizer", 10 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, CloseDecoder );
vlc_module_end();
/*****************************************************************************
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ')
- && p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2',' ')
+ && p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2','b') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- p_dec->p_sys->b_packetizer = VLC_FALSE;
+
+ /* Misc init */
+ p_sys->b_packetizer = VLC_FALSE;
+ p_sys->i_state = STATE_NOSYNC;
+ aout_DateSet( &p_sys->end_date, 0 );
+
+ p_sys->bytestream = block_BytestreamInit( p_dec );
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('a','5','2',' ');
+
+ /* Set callback */
+ p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
return VLC_SUCCESS;
}
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- p_dec->p_sys->i_state = STATE_NOSYNC;
-
- p_dec->p_sys->p_out_buffer = NULL;
- aout_DateSet( &p_dec->p_sys->end_date, 0 );
-
- p_dec->p_sys->p_aout = NULL;
- p_dec->p_sys->p_aout_input = NULL;
- p_dec->p_sys->p_aout_buffer = NULL;
- p_dec->p_sys->aout_format.i_format = VLC_FOURCC('a','5','2',' ');
-
- p_dec->p_sys->p_sout_input = NULL;
- p_dec->p_sys->p_sout_buffer = NULL;
- p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
- p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
-
- p_dec->p_sys->p_chain = NULL;
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function is called just after the thread is launched.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
uint8_t p_header[A52_HEADER_SIZE];
+ uint8_t *p_buf;
+ void *p_out_buffer;
- if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+ if( !pp_block || !*pp_block ) return NULL;
+
+ if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
{
/* We've just started the stream, wait for the first PTS. */
- block_Release( p_block );
- return VLC_SUCCESS;
+ block_Release( *pp_block );
+ return NULL;
}
- if( p_block->b_discontinuity )
+ if( (*pp_block)->b_discontinuity )
{
- p_sys->i_state = STATE_SYNC;
+ p_sys->i_state = STATE_NOSYNC;
}
- if( p_sys->p_chain )
- {
- block_ChainAppend( &p_sys->p_chain, p_block );
- }
- else
- {
- block_ChainAppend( &p_sys->p_chain, p_block );
- p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
- }
+ block_BytestreamPush( &p_sys->bytestream, *pp_block );
while( 1 )
{
switch( p_sys->i_state )
{
-
case STATE_NOSYNC:
while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
== VLC_SUCCESS )
}
if( p_sys->i_state != STATE_SYNC )
{
- if( block_PeekByte( &p_sys->bytestream, p_header )
- == VLC_SUCCESS && p_header[0] == 0x0b )
- {
- /* Start of a sync word, need more data */
- return VLC_SUCCESS;
- }
-
- block_ChainRelease( p_sys->p_chain );
- p_sys->p_chain = NULL;
+ block_BytestreamFlush( &p_sys->bytestream );
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
case STATE_SYNC:
/* New frame, set the Presentation Time Stamp */
- p_sys->pts = p_sys->bytestream.p_block->i_pts;
- if( p_sys->pts != 0 &&
- p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+ if( p_sys->i_pts != 0 &&
+ p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->end_date, p_sys->pts );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
p_sys->i_state = STATE_HEADER;
- break;
case STATE_HEADER:
/* Get A/52 frame header (A52_HEADER_SIZE bytes) */
A52_HEADER_SIZE ) != VLC_SUCCESS )
{
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
/* Check if frame is valid and get frame info */
p_sys->i_state = STATE_NOSYNC;
break;
}
- p_sys->i_state = STATE_DATA;
+ p_sys->i_state = STATE_NEXT_SYNC;
- case STATE_DATA:
- /* TODO: If p_block == NULL, flush the buffer without checking the
+ case STATE_NEXT_SYNC:
+ /* TODO: If pp_block == NULL, flush the buffer without checking the
* next sync word */
- /* Check if next expected frame contains the sync word */
- if( block_PeekOffsetBytes( &p_sys->bytestream,
- p_sys->i_frame_size, p_header, 2 )
- != VLC_SUCCESS )
- {
- /* Need more data */
- return VLC_SUCCESS;
- }
-
- if( p_header[0] != 0x0b || p_header[1] != 0x77 )
- {
- msg_Dbg( p_dec, "emulated sync word "
- "(no sync on following frame)" );
- p_sys->i_state = STATE_NOSYNC;
- block_SkipByte( &p_sys->bytestream );
- break;
+ /* Check if next expected frame contains the sync word */
+ if( block_PeekOffsetBytes( &p_sys->bytestream,
+ p_sys->i_frame_size, p_header, 2 )
+ != VLC_SUCCESS )
+ {
+ /* Need more data */
+ return NULL;
}
- if( !p_sys->p_out_buffer )
- if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS )
+ if( p_header[0] != 0x0b || p_header[1] != 0x77 )
{
- return VLC_EGENERIC;
+ msg_Dbg( p_dec, "emulated sync word "
+ "(no sync on following frame)" );
+ p_sys->i_state = STATE_NOSYNC;
+ block_SkipByte( &p_sys->bytestream );
+ break;
}
+ p_sys->i_state = STATE_SEND_DATA;
+ break;
- /* Copy the whole frame into the buffer */
- if( block_GetBytes( &p_sys->bytestream, p_sys->p_out_buffer,
- p_sys->i_frame_size ) != VLC_SUCCESS )
+ case STATE_GET_DATA:
+ /* Make sure we have enough data.
+ * (Not useful if we went through NEXT_SYNC) */
+ if( block_WaitBytes( &p_sys->bytestream,
+ p_sys->i_frame_size ) != VLC_SUCCESS )
{
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
+ p_sys->i_state = STATE_SEND_DATA;
- p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
+ case STATE_SEND_DATA:
+ if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
+ {
+ //p_dec->b_error = VLC_TRUE;
+ return NULL;
+ }
- SendOutBuffer( p_dec );
- p_sys->i_state = STATE_NOSYNC;
+ /* Copy the whole frame into the buffer. When we reach this point
+ * we already know we have enough data available. */
+ block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
/* Make sure we don't reuse the same pts twice */
- if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
- p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
- }
- }
+ if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * EndDecoder: clean up the decoder
- *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
-{
- if( p_dec->p_sys->p_aout_input != NULL )
- {
- if( p_dec->p_sys->p_aout_buffer )
- {
- aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
- p_dec->p_sys->p_aout_input,
- p_dec->p_sys->p_aout_buffer );
- }
+ /* So p_block doesn't get re-added several times */
+ *pp_block = block_BytestreamPop( &p_sys->bytestream );
- aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
- }
+ p_sys->i_state = STATE_NOSYNC;
- if( p_dec->p_sys->p_sout_input != NULL )
- {
- if( p_dec->p_sys->p_sout_buffer )
- {
- sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
- p_dec->p_sys->p_sout_buffer );
+ return p_out_buffer;
}
-
- sout_InputDelete( p_dec->p_sys->p_sout_input );
}
- if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
-
- free( p_dec->p_sys );
-
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
- * GetOutBuffer:
+ * CloseDecoder: clean up the decoder
*****************************************************************************/
-static int GetOutBuffer( decoder_t *p_dec, uint8_t **pp_out_buffer )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t*)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_ret;
- if( p_sys->b_packetizer )
- {
- i_ret = GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
- *pp_out_buffer =
- p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
- }
- else
- {
- i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
- *pp_out_buffer =
- p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer : NULL;
- }
+ block_BytestreamRelease( &p_sys->bytestream );
- return i_ret;
+ free( p_sys );
}
/*****************************************************************************
- * GetAoutBuffer:
+ * GetOutBuffer:
*****************************************************************************/
-static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ uint8_t *p_buf;
- if( p_sys->p_aout_input != NULL &&
- ( p_sys->aout_format.i_rate != p_sys->i_rate
- || p_sys->aout_format.i_original_channels != p_sys->i_channels_conf
- || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
+ if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
{
- /* Parameters changed - this should not happen. */
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- p_sys->p_aout_input = NULL;
- }
+ msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
+ p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
- /* Creating the audio input if not created yet. */
- if( p_sys->p_aout_input == NULL )
- {
- p_sys->aout_format.i_rate = p_sys->i_rate;
- p_sys->aout_format.i_original_channels = p_sys->i_channels_conf;
- p_sys->aout_format.i_physical_channels
- = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
- p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size;
- p_sys->aout_format.i_frame_length = A52_FRAME_NB;
aout_DateInit( &p_sys->end_date, p_sys->i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
- p_sys->p_aout_input = aout_DecNew( p_dec,
- &p_sys->p_aout,
- &p_sys->aout_format );
- if( p_sys->p_aout_input == NULL )
- {
- *pp_buffer = NULL;
- return VLC_EGENERIC;
- }
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
- *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
- A52_FRAME_NB );
- if( *pp_buffer == NULL )
+ p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
+ p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+ p_dec->fmt_out.audio.i_bitrate = p_sys->i_bit_rate;
+ p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
+ p_dec->fmt_out.audio.i_frame_length = A52_FRAME_NB;
+
+ p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
+
+ if( p_sys->b_packetizer )
{
- return VLC_EGENERIC;
+ block_t *p_sout_buffer = GetSoutBuffer( p_dec );
+ p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
+ *pp_out_buffer = p_sout_buffer;
+ }
+ else
+ {
+ aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
+ p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
+ *pp_out_buffer = p_aout_buffer;
}
- (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
- (*pp_buffer)->end_date =
- aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
-
- return VLC_SUCCESS;
+ return p_buf;
}
/*****************************************************************************
- * GetSoutBuffer:
+ * GetAoutBuffer:
*****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ aout_buffer_t *p_buf;
- if( p_sys->p_sout_input != NULL &&
- ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
- || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
- {
- /* Parameters changed - this should not happen. */
- }
-
- /* Creating the sout input if not created yet. */
- if( p_sys->p_sout_input == NULL )
- {
- p_sys->sout_format.i_sample_rate = p_sys->i_rate;
- p_sys->sout_format.i_channels = p_sys->i_channels;
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = p_sys->i_bit_rate;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
+ p_buf = p_dec->pf_aout_buffer_new( p_dec, A52_FRAME_NB );
+ if( p_buf == NULL ) return NULL;
- aout_DateInit( &p_sys->end_date, p_sys->i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
+ p_buf->start_date = aout_DateGet( &p_sys->end_date );
+ p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
- p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
- if( p_sys->p_sout_input == NULL )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- *pp_buffer = NULL;
- return VLC_EGENERIC;
- }
- msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
- p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
- }
-
- *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
- p_sys->i_frame_size );
- if( *pp_buffer == NULL )
- {
- return VLC_EGENERIC;
- }
-
- (*pp_buffer)->i_pts =
- (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
-
- (*pp_buffer)->i_length =
- aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB )
- - (*pp_buffer)->i_pts;
-
- return VLC_SUCCESS;
+ return p_buf;
}
/*****************************************************************************
- * SendOutBuffer:
+ * GetSoutBuffer:
*****************************************************************************/
-static int SendOutBuffer( decoder_t *p_dec )
+static block_t *GetSoutBuffer( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
- if( p_sys->b_packetizer )
- {
- sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
- p_sys->p_sout_buffer = NULL;
- }
- else
- {
- /* We have all we need, send the buffer to the aout core. */
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
- p_sys->p_aout_buffer );
- p_sys->p_aout_buffer = NULL;
- }
+ p_block = block_New( p_dec, p_sys->i_frame_size );
+ if( p_block == NULL ) return NULL;
- p_sys->p_out_buffer = NULL;
+ p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
- return VLC_SUCCESS;
+ p_block->i_length = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) -
+ p_block->i_pts;
+
+ return p_block;
}
/*****************************************************************************
* adpcm.c : adpcm variant audio decoder
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: adpcm.c,v 1.15 2003/11/05 01:47:40 fenrir Exp $
+ * $Id: adpcm.c,v 1.16 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
#include <stdlib.h> /* malloc(), free() */
#include <vlc/vlc.h>
-#include <vlc/aout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-static int Open ( vlc_object_t * );
+static int OpenDecoder( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
+
+static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
vlc_module_begin();
set_description( _("ADPCM audio decoder") );
set_capability( "decoder", 50 );
- set_callbacks( Open, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
vlc_module_end();
-
/*****************************************************************************
* Local prototypes
*****************************************************************************/
struct decoder_sys_t
{
- WAVEFORMATEX *p_wf;
enum adpcm_codec_e codec;
int i_block;
int i_samplesperblock;
- /* audio output */
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
- audio_sample_format_t output_format;
-
- audio_date_t date;
+ audio_date_t end_date;
};
-static int Init ( decoder_t * );
-static int Decode( decoder_t *, block_t * );
-static int End ( decoder_t * );
-
-
-
-static void DecodeAdpcmMs ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmImaWav ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmImaQT ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmDk4 ( decoder_sys_t *, int16_t *, uint8_t * );
-static void DecodeAdpcmDk3 ( decoder_sys_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmMs ( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmImaWav( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmImaQT ( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmDk4 ( decoder_t *, int16_t *, uint8_t * );
+static void DecodeAdpcmDk3 ( decoder_t *, int16_t *, uint8_t * );
static int pi_channels_maps[6] =
{
0, -256, 0, 64, 0, -208, -232
};
-
/*****************************************************************************
* 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 Open( vlc_object_t *p_this )
+static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- switch( p_dec->p_fifo->i_fourcc )
+ switch( p_dec->fmt_in.i_codec )
{
case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
-
- p_dec->pf_init = Init;
- p_dec->pf_decode = Decode;
- p_dec->pf_end = End;
-
- p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
- return VLC_SUCCESS;
-
+ break;
default:
return VLC_EGENERIC;
}
-}
-
-/*****************************************************************************
- * Init:
- *****************************************************************************/
-static int Init ( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- WAVEFORMATEX *p_wf;
- if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+ /* Allocate the memory needed to store the decoder's structure */
+ if( ( p_dec->p_sys = p_sys =
+ (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
- msg_Err( p_dec, "unknown raw format" );
+ msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- if( p_wf->nChannels < 1 || p_wf->nChannels > 2 )
+ if( p_dec->fmt_in.audio.i_channels <= 0 ||
+ p_dec->fmt_in.audio.i_channels > 5 )
{
- msg_Err( p_dec, "bad channels count(1-2)" );
+ msg_Err( p_dec, "bad channels count(1-5)" );
return VLC_EGENERIC;
}
- if( p_wf->nSamplesPerSec <= 0 )
+
+ if( p_dec->fmt_in.audio.i_rate <= 0 )
{
msg_Err( p_dec, "bad samplerate" );
return VLC_EGENERIC;
}
- p_sys->p_wf = p_wf;
- switch( p_dec->p_fifo->i_fourcc )
+ switch( p_dec->fmt_in.i_codec )
{
case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
p_sys->codec = ADPCM_IMA_QT;
break;
}
- if( ( p_sys->i_block = p_wf->nBlockAlign ) <= 0 )
+ if( 1 )//( p_sys->i_block = p_wf->nBlockAlign ) <= 0 )
{
- p_sys->i_block = p_sys->codec==ADPCM_IMA_QT ? 34*p_wf->nChannels:1024;
+ p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ?
+ 34 * p_dec->fmt_in.audio.i_channels : 1024;
msg_Warn( p_dec, "block size undefined, -> using %d", p_sys->i_block );
}
/* calculate samples per block */
switch( p_sys->codec )
{
- case ADPCM_IMA_QT:
- p_sys->i_samplesperblock = 64;
- break;
- case ADPCM_IMA_WAV:
- p_sys->i_samplesperblock =
- 2 * ( p_sys->i_block - 4 * p_wf->nChannels )/ p_wf->nChannels;
- break;
- case ADPCM_MS:
- p_sys->i_samplesperblock =
- 2 * (p_sys->i_block - 7 * p_wf->nChannels)/p_wf->nChannels + 2;
- break;
- case ADPCM_DK4:
- p_sys->i_samplesperblock =
- 2 * (p_sys->i_block - 4 * p_wf->nChannels)/p_wf->nChannels + 1;
- break;
- case ADPCM_DK3:
- p_wf->nChannels = 2;
- p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
- break;
+ case ADPCM_IMA_QT:
+ p_sys->i_samplesperblock = 64;
+ break;
+ case ADPCM_IMA_WAV:
+ p_sys->i_samplesperblock =
+ 2 * ( p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels ) /
+ p_dec->fmt_in.audio.i_channels;
+ break;
+ case ADPCM_MS:
+ p_sys->i_samplesperblock =
+ 2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels) /
+ p_dec->fmt_in.audio.i_channels + 2;
+ break;
+ case ADPCM_DK4:
+ p_sys->i_samplesperblock =
+ 2 * (p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels) /
+ p_dec->fmt_in.audio.i_channels + 1;
+ break;
+ case ADPCM_DK3:
+ p_dec->fmt_in.audio.i_channels = 2;
+ p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
+ break;
}
- msg_Dbg( p_dec,
- "format: samplerate:%dHz channels:%d bits/sample:%d blockalign:%d samplesperblock %d",
- p_wf->nSamplesPerSec, p_wf->nChannels,
- p_wf->wBitsPerSample, p_wf->nBlockAlign,
+
+ msg_Dbg( p_dec, "format: samplerate:%dHz channels:%d bits/sample:%d "
+ "blockalign:%d samplesperblock %d",
+ p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
+ p_dec->fmt_in.audio.i_bitspersample, p_sys->i_block,
p_sys->i_samplesperblock );
- p_sys->output_format.i_format = AOUT_FMT_S16_NE;
- p_sys->output_format.i_rate = p_wf->nSamplesPerSec;
- p_sys->output_format.i_physical_channels =
- p_sys->output_format.i_original_channels =
- pi_channels_maps[p_wf->nChannels];
+ p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
+ p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
+ p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
+ pi_channels_maps[p_dec->fmt_in.audio.i_channels];
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = aout_DecNew( p_dec,
- &p_sys->p_aout, &p_sys->output_format);
- if( p_sys->p_aout_input == NULL )
- {
- msg_Err( p_dec, "cannot create aout" );
- return VLC_EGENERIC;
- }
+ aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+ aout_DateSet( &p_sys->end_date, 0 );
- aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
- aout_DateSet( &p_sys->date, 0 );
+ p_dec->pf_decode_audio = DecodeBlock;
return VLC_SUCCESS;
}
/*****************************************************************************
- * Decode:
+ * DecodeBlock:
*****************************************************************************/
-static int Decode( decoder_t *p_dec, block_t *p_block )
+static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- mtime_t i_pts = p_block->i_pts;
- uint8_t *p_data = p_block->p_buffer;
- int i_data = p_block->i_buffer;
+ block_t *p_block;
- while( i_data >= p_sys->i_block )
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
+
+ if( p_block->i_pts != 0 &&
+ p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
+ {
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
+ }
+ else if( !aout_DateGet( &p_sys->end_date ) )
{
- aout_buffer_t *out;
+ /* We've just started the stream, wait for the first PTS. */
+ block_Release( p_block );
+ return NULL;
+ }
- if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->date ) )
- {
- aout_DateSet( &p_sys->date, i_pts );
- }
- else if( !aout_DateGet( &p_sys->date ) )
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
- i_pts = 0;
+ /* Don't re-use the same pts twice */
+ p_block->i_pts = 0;
+
+ if( p_block->i_buffer >= p_sys->i_block )
+ {
+ aout_buffer_t *p_out;
- out = aout_DecNewBuffer( p_sys->p_aout,
- p_sys->p_aout_input,
- p_sys->i_samplesperblock );
- if( out == NULL )
+ p_out = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_samplesperblock );
+ if( p_out == NULL )
{
- msg_Err( p_dec, "cannot get aout buffer" );
block_Release( p_block );
- return VLC_EGENERIC;
+ return NULL;
}
- out->start_date = aout_DateGet( &p_sys->date );
- out->end_date = aout_DateIncrement( &p_sys->date,
- p_sys->i_samplesperblock );
+
+ p_out->start_date = aout_DateGet( &p_sys->end_date );
+ p_out->end_date =
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_samplesperblock );
switch( p_sys->codec )
{
- case ADPCM_IMA_QT:
- DecodeAdpcmImaQT( p_sys, (int16_t*)out->p_buffer, p_data );
- break;
- case ADPCM_IMA_WAV:
- DecodeAdpcmImaWav( p_sys, (int16_t*)out->p_buffer, p_data );
- break;
- case ADPCM_MS:
- DecodeAdpcmMs( p_sys, (int16_t*)out->p_buffer, p_data );
- break;
- case ADPCM_DK4:
- DecodeAdpcmDk4( p_sys, (int16_t*)out->p_buffer, p_data );
- break;
- case ADPCM_DK3:
- DecodeAdpcmDk3( p_sys, (int16_t*)out->p_buffer, p_data );
- break;
- default:
- break;
+ case ADPCM_IMA_QT:
+ DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer,
+ p_block->p_buffer );
+ break;
+ case ADPCM_IMA_WAV:
+ DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer,
+ p_block->p_buffer );
+ break;
+ case ADPCM_MS:
+ DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer,
+ p_block->p_buffer );
+ break;
+ case ADPCM_DK4:
+ DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer,
+ p_block->p_buffer );
+ break;
+ case ADPCM_DK3:
+ DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer,
+ p_block->p_buffer );
+ break;
+ default:
+ break;
}
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
- p_data += p_sys->i_block;
- i_data -= p_sys->i_block;
+ p_block->p_buffer += p_out->i_nb_bytes;
+ p_block->i_buffer -= p_out->i_nb_bytes;
+ return p_out;
}
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
- * End:
+ * CloseDecoder:
*****************************************************************************/
-static int End ( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_sys->p_aout_input )
- {
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
free( p_sys );
-
- return VLC_SUCCESS;
}
+/*****************************************************************************
+ * Local functions
+ *****************************************************************************/
#define CLAMP( v, min, max ) \
if( (v) < (min) ) (v) = (min); \
if( (v) > (max) ) (v) = (max)
return( i_predictor );
}
-static void DecodeAdpcmMs( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample,
+ uint8_t *p_buffer )
{
+ decoder_sys_t *p_sys = p_dec->p_sys;
adpcm_ms_channel_t channel[2];
int i_nibbles;
int b_stereo;
int i_block_predictor;
- b_stereo = p_sys->p_wf->nChannels == 2 ? 1 : 0;
+ b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
GetByte( i_block_predictor );
CLAMP( i_block_predictor, 0, 6 );
*p_sample++ = channel[0].i_sample1;
}
- for( i_nibbles = 2 *( p_sys->i_block - 7 * p_sys->p_wf->nChannels );
- i_nibbles > 0; i_nibbles -= 2,p_buffer++ )
+ for( i_nibbles = 2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels);
+ i_nibbles > 0; i_nibbles -= 2, p_buffer++ )
{
*p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4);
*p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0],
return( p_channel->i_predictor );
}
-static void DecodeAdpcmImaWav( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
+ uint8_t *p_buffer )
{
+ decoder_sys_t *p_sys = p_dec->p_sys;
adpcm_ima_wav_channel_t channel[2];
int i_nibbles;
int b_stereo;
- b_stereo = p_sys->p_wf->nChannels == 2 ? 1 : 0;
+ b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
GetWord( channel[0].i_predictor );
GetByte( channel[0].i_step_index );
/*
* Ima4 in QT file
*/
-static void DecodeAdpcmImaQT( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample,
+ uint8_t *p_buffer )
{
adpcm_ima_wav_channel_t channel[2];
int i_nibbles;
int i_ch;
int i_step;
- i_step = p_sys->p_wf->nChannels;
+ i_step = p_dec->fmt_in.audio.i_channels;
- for( i_ch = 0; i_ch < p_sys->p_wf->nChannels; i_ch++ )
+ for( i_ch = 0; i_ch < p_dec->fmt_in.audio.i_channels; i_ch++ )
{
/* load preambule */
channel[i_ch].i_predictor = (int16_t)((( ( p_buffer[0] << 1 )|( p_buffer[1] >> 7 ) ))<<7);
/*
* Dk4
*/
-
-static void DecodeAdpcmDk4( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample,
+ uint8_t *p_buffer )
{
+ decoder_sys_t *p_sys = p_dec->p_sys;
adpcm_ima_wav_channel_t channel[2];
int i_nibbles;
int b_stereo;
- b_stereo = p_sys->p_wf->nChannels == 2 ? 1 : 0;
+ b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
GetWord( channel[0].i_predictor );
GetByte( channel[0].i_step_index );
/*
* Dk3
*/
-static void DecodeAdpcmDk3( decoder_sys_t *p_sys, int16_t *p_sample, uint8_t *p_buffer )
+static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample,
+ uint8_t *p_buffer )
{
+ decoder_sys_t *p_sys = p_dec->p_sys;
uint8_t *p_end = &p_buffer[p_sys->i_block];
adpcm_ima_wav_channel_t sum;
adpcm_ima_wav_channel_t diff;
}
}
}
-
* araw.c: Pseudo audio decoder; for raw pcm data
*****************************************************************************
* Copyright (C) 2001, 2003 VideoLAN
- * $Id: araw.c,v 1.23 2003/11/08 04:57:56 fenrir Exp $
+ * $Id: araw.c,v 1.24 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
-#include <vlc/vlc.h>
-#include <vlc/aout.h>
+#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#include <vlc/sout.h>
-
#include "codecs.h"
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-static int DecoderOpen ( vlc_object_t * );
+static int DecoderOpen ( vlc_object_t * );
+static void DecoderClose( vlc_object_t * );
-static int EncoderOpen ( vlc_object_t *p_this );
-static void EncoderClose ( vlc_object_t *p_this );
+static int EncoderOpen ( vlc_object_t * );
+static void EncoderClose( vlc_object_t * );
vlc_module_begin();
/* audio decoder module */
set_description( _("Raw/Log Audio decoder") );
set_capability( "decoder", 50 );
- set_callbacks( DecoderOpen, NULL );
+ set_callbacks( DecoderOpen, DecoderClose );
/* audio encoder submodule */
add_submodule();
set_description( _("Raw audio encoder") );
- set_capability( "audio encoder", 10 );
+ set_capability( "encoder", 10 );
set_callbacks( EncoderOpen, EncoderClose );
vlc_module_end();
-
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int DecoderInit ( decoder_t * );
-static int DecoderDecode( decoder_t *, block_t * );
-static int DecoderEnd ( decoder_t * );
+static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
+static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
struct decoder_sys_t
{
- WAVEFORMATEX *p_wf;
-
- int16_t *p_logtos16; // used with m/alaw to int16_t
-
- /* Output properties */
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
- audio_sample_format_t output_format;
+ int16_t *p_logtos16; /* used with m/alaw to int16_t */
- audio_date_t date;
+ audio_date_t end_date;
};
-
-static block_t *EncoderEncode( encoder_t *, aout_buffer_t *p_aout_buf );
-
-/*****************************************************************************
- * DecoderOpen: probe the decoder and return score
- *****************************************************************************
- * Tries to launch a decoder and return score so that the interface is able
- * to choose.
- *****************************************************************************/
-static int DecoderOpen( vlc_object_t *p_this )
-{
- decoder_t *p_dec = (decoder_t*)p_this;
-
- switch( p_dec->p_fifo->i_fourcc )
- {
- case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
- case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
- case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
-
- case VLC_FOURCC('a','l','a','w'):
- case VLC_FOURCC('u','l','a','w'):
- p_dec->pf_init = DecoderInit;
- p_dec->pf_decode = DecoderDecode;
- p_dec->pf_end = DecoderEnd;
-
- p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
- return VLC_SUCCESS;
-
- default:
- return VLC_EGENERIC;
- }
-}
-
static int pi_channels_maps[6] =
{
0,
};
/*****************************************************************************
- * DecoderInit: initialize data before entering main loop
+ * DecoderOpen: probe the decoder and return score
*****************************************************************************/
-static int DecoderInit( decoder_t *p_dec )
+static int DecoderOpen( vlc_object_t *p_this )
{
- decoder_sys_t *p_sys = p_dec->p_sys;
+ decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
+
+ switch( p_dec->fmt_in.i_codec )
+ {
+ /* from wav/avi/asf file */
+ case VLC_FOURCC('a','r','a','w'):
+ /* _signed_ big endian samples (mov)*/
+ case VLC_FOURCC('t','w','o','s'):
+ /* _signed_ little endian samples (mov)*/
+ case VLC_FOURCC('s','o','w','t'):
+
+ case VLC_FOURCC('a','l','a','w'):
+ case VLC_FOURCC('u','l','a','w'):
+ break;
+
+ default:
+ return VLC_EGENERIC;
+ }
- WAVEFORMATEX *p_wf;
- if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+ /* Allocate the memory needed to store the decoder's structure */
+ if( ( p_dec->p_sys = p_sys =
+ (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
- msg_Err( p_dec, "unknown raw format" );
+ msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- if( p_wf->nChannels <= 0 || p_wf->nChannels > 5 )
+ if( p_dec->fmt_in.audio.i_channels <= 0 ||
+ p_dec->fmt_in.audio.i_channels > 5 )
{
msg_Err( p_dec, "bad channels count(1-5)" );
return VLC_EGENERIC;
}
- if( p_wf->nSamplesPerSec <= 0 )
+
+ if( p_dec->fmt_in.audio.i_rate <= 0 )
{
msg_Err( p_dec, "bad samplerate" );
return VLC_EGENERIC;
}
- p_sys->p_wf = p_wf;
p_sys->p_logtos16 = NULL;
- /* fixing some values */
- if( p_wf->nBlockAlign == 0 &&
- ( p_wf->wFormatTag == WAVE_FORMAT_PCM ||
- p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ) )
- {
- p_wf->nBlockAlign = ( p_wf->wBitsPerSample + 7 ) / 8 * p_wf->nChannels;
- }
+ msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
+ p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
+ p_dec->fmt_in.audio.i_bitspersample );
- msg_Dbg( p_dec,
- "samplerate:%dHz channels:%d bits/sample:%d blockalign:%d",
- p_wf->nSamplesPerSec, p_wf->nChannels,
- p_wf->wBitsPerSample, p_wf->nBlockAlign );
-
- if( p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )
+ if( 0 /* p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT */ )
{
- switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+ switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
{
- case( 4 ):
- p_sys->output_format.i_format = VLC_FOURCC('f','l','3','2');
- break;
- case( 8 ):
- p_sys->output_format.i_format = VLC_FOURCC('f','l','6','4');
- break;
- default:
- msg_Err( p_dec, "bad parameters(bits/sample)" );
- return VLC_EGENERIC;
+ case 4:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
+ break;
+ case 8:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
+ break;
+ default:
+ msg_Err( p_dec, "bad parameters(bits/sample)" );
+ return VLC_EGENERIC;
}
}
else
{
- if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
+ if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
{
- switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+ switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
{
- case( 1 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
- break;
- case( 2 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','1','6','b');
- break;
- case( 3 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','2','4','b');
- break;
- case( 4 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','3','2','b');
- break;
- default:
- msg_Err( p_dec, "bad parameters(bits/sample)" );
- return VLC_EGENERIC;
+ case 1:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
+ break;
+ case 2:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
+ break;
+ case 3:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
+ break;
+ case 4:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
+ break;
+ default:
+ msg_Err( p_dec, "bad parameters(bits/sample)" );
+ return VLC_EGENERIC;
}
}
- else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
+ else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
{
- switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+ switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
{
- case( 1 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
- break;
- case( 2 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','1','6','l');
- break;
- case( 3 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','2','4','l');
- break;
- case( 4 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','3','2','l');
- break;
- default:
- msg_Err( p_dec, "bad parameters(bits/sample)" );
- return VLC_EGENERIC;
+ case 1:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
+ break;
+ case 2:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
+ break;
+ case 3:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
+ break;
+ case 4:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
+ break;
+ default:
+ msg_Err( p_dec, "bad parameters(bits/sample)" );
+ return VLC_EGENERIC;
}
}
- else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
+ else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
{
- switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
+ switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
{
- case( 1 ):
- p_sys->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
- break;
- case( 2 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','1','6','l');
- break;
- case( 3 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','2','4','l');
- break;
- case( 4 ):
- p_sys->output_format.i_format = VLC_FOURCC('s','3','2','l');
- break;
- default:
- msg_Err( p_dec, "bad parameters(bits/sample)" );
- return VLC_EGENERIC;
+ case 1:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
+ break;
+ case 2:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
+ break;
+ case 3:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
+ break;
+ case 4:
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
+ break;
+ default:
+ msg_Err( p_dec, "bad parameters(bits/sample)" );
+ return VLC_EGENERIC;
}
}
- else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
+ else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
{
- p_sys->output_format.i_format = AOUT_FMT_S16_NE;
+ p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
p_sys->p_logtos16 = alawtos16;
- p_wf->wBitsPerSample = 8;
+ p_dec->fmt_in.audio.i_bitspersample = 8;
}
- else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
+ else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
{
- p_sys->output_format.i_format = AOUT_FMT_S16_NE;
+ p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
p_sys->p_logtos16 = ulawtos16;
- p_wf->wBitsPerSample = 8;
+ p_dec->fmt_in.audio.i_bitspersample = 8;
}
}
- p_sys->output_format.i_rate = p_wf->nSamplesPerSec;
- p_sys->output_format.i_physical_channels =
- p_sys->output_format.i_original_channels = pi_channels_maps[p_wf->nChannels];
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
+ p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
+ pi_channels_maps[p_dec->fmt_in.audio.i_channels];
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
- &p_sys->output_format );
- if( p_sys->p_aout_input == NULL )
- {
- msg_Err( p_dec, "cannot create aout" );
- return VLC_EGENERIC;
- }
+ aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+ aout_DateSet( &p_sys->end_date, 0 );
- aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
- aout_DateSet( &p_sys->date, 0 );
+ p_dec->pf_decode_audio = DecodeBlock;
return VLC_SUCCESS;
}
-/*****************************************************************************
- * DecoderDecode: decodes a frame
- *****************************************************************************/
-static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
+/****************************************************************************
+ * DecodeBlock: the whole thing
+ ****************************************************************************
+ * This function must be fed with whole samples (see nBlockAlign).
+ ****************************************************************************/
+static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_size = p_block->i_buffer;
- uint8_t *p = p_block->p_buffer;
- int i_samples; // per channels
+ block_t *p_block;
+ int i_samples;
- if( p_sys->p_wf->nBlockAlign > 0 )
- {
- /* Align it (it should already be aligned by demuxer) */
- i_size -= i_size % p_sys->p_wf->nBlockAlign;
- }
- if( i_size < p_sys->p_wf->nBlockAlign )
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
- i_samples = i_size / ( ( p_sys->p_wf->wBitsPerSample + 7 ) / 8 ) /
- p_sys->p_wf->nChannels;
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
- if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
+ if( p_block->i_pts != 0 &&
+ p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->date, p_block->i_pts );
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
}
- else if( !aout_DateGet( &p_sys->date ) )
+ else if( !aout_DateGet( &p_sys->end_date ) )
{
+ /* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
- while( i_samples > 0 )
+ /* Don't re-use the same pts twice */
+ p_block->i_pts = 0;
+
+ i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
+ p_dec->fmt_in.audio.i_channels;
+
+
+ /* Create chunks of max 1024 samples */
+ if( i_samples > 0 )
{
- int i_copy = __MIN( i_samples, 1024 );
- aout_buffer_t *out;
+ aout_buffer_t *p_out;
+ i_samples = __MIN( i_samples, 1024 );
- out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, i_copy );
- if( out == NULL )
+ p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
+ if( p_out == NULL )
{
- msg_Err( p_dec, "cannot get aout buffer" );
block_Release( p_block );
- return VLC_EGENERIC;
+ return NULL;
}
- out->start_date = aout_DateGet( &p_sys->date );
- out->end_date = aout_DateIncrement( &p_sys->date, i_copy );
+ p_out->start_date = aout_DateGet( &p_sys->end_date );
+ p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
if( p_sys->p_logtos16 )
{
- int16_t *s = (int16_t*)out->p_buffer;
+ int16_t *s = (int16_t*)p_out->p_buffer;
unsigned int i;
- for( i = 0; i < out->i_nb_bytes / 2; i++ )
+ for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
{
- *s++ = p_sys->p_logtos16[*p++];
+ *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
+ p_block->i_buffer++;
}
}
else
{
- memcpy( out->p_buffer, p, out->i_nb_bytes );
-
- p += out->i_nb_bytes;
+ memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
+ p_block->p_buffer += p_out->i_nb_bytes;
+ p_block->i_buffer -= p_out->i_nb_bytes;
}
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
-
- i_samples -= i_copy;
+ return p_out;
}
+
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
- * DecoderEnd : faad decoder thread destruction
+ * DecoderClose: decoder destruction
*****************************************************************************/
-static int DecoderEnd( decoder_t *p_dec )
+static void DecoderClose( vlc_object_t *p_this )
{
- decoder_sys_t *p_sys = p_dec->p_sys;
+ decoder_t *p_dec = (decoder_t *)p_this;
- if( p_sys->p_aout_input )
- {
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
- free( p_sys );
-
- return VLC_SUCCESS;
+ free( p_dec->p_sys );
}
/*****************************************************************************
* EncoderOpen:
*****************************************************************************/
-static int EncoderOpen ( vlc_object_t *p_this )
+static int EncoderOpen( vlc_object_t *p_this )
{
encoder_t *p_enc = (encoder_t *)p_this;
- if( p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'b' ) &&
- p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'l' ) )
+ if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
+ p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
{
msg_Warn( p_enc, "unhandled input format" );
return VLC_EGENERIC;
}
- switch( p_enc->i_fourcc )
+ switch( p_enc->fmt_out.i_codec )
{
case VLC_FOURCC( 's', '1', '6', 'b' ):
case VLC_FOURCC( 's', '1', '6', 'l' ):
}
p_enc->p_sys = NULL;
- p_enc->pf_header = NULL;
p_enc->pf_encode_audio = EncoderEncode;
- p_enc->pf_encode_video = NULL;
- p_enc->i_extra_data = 0;
- p_enc->p_extra_data = NULL;
return VLC_SUCCESS;
}
block_t *p_block = NULL;
unsigned int i;
- if( p_enc->i_fourcc == p_enc->format.audio.i_format )
+ if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
{
if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
{
- memcpy( p_block->p_buffer, p_aout_buf->p_buffer, p_aout_buf->i_nb_bytes );
+ memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
+ p_aout_buf->i_nb_bytes );
}
}
- else if( p_enc->i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
+ else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
{
if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
{
uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
- if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
+ if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
{
p_src++;
}
}
}
}
- else if( p_enc->i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
+ else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
{
if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
{
int8_t *p_dst = (int8_t*)p_block->p_buffer;
int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
- if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
+ if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
{
p_src++;
}
if( p_block )
{
p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
- p_block->i_length = (int64_t)p_aout_buf->i_nb_samples * (int64_t)1000000 /
- p_enc->format.audio.i_rate;
+ p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
+ (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;
}
return p_block;
}
-
-
* cinepak.c: cinepak video decoder
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: cinepak.c,v 1.2 2003/10/25 00:49:13 sam Exp $
+ * $Id: cinepak.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* Cinepak properties
*/
cinepak_context_t *p_context;
-
- /*
- * Output properties
- */
- vout_thread_t *p_vout;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int OpenDecoder( vlc_object_t * );
-static int InitDecoder( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static int OpenDecoder( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
+static picture_t *DecodeBlock ( decoder_t *, block_t ** );
static int cinepak_decode_frame( cinepak_context_t *, int, uint8_t * );
vlc_module_begin();
set_description( _("Cinepak video decoder") );
set_capability( "decoder", 70 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
vlc_module_end();
/*****************************************************************************
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
+ vlc_value_t val;
- switch( p_dec->p_fifo->i_fourcc )
+ switch( p_dec->fmt_in.i_codec )
{
case VLC_FOURCC('c','v','i','d'):
case VLC_FOURCC('C','V','I','D'):
}
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- vlc_value_t val;
-
- p_sys->p_vout = NULL;
-
if( !(p_sys->p_context = malloc( sizeof( cinepak_context_t ) ) ) )
{
msg_Err( p_dec, "out of memory" );
var_Get( p_dec, "grayscale", &val );
p_sys->p_context->b_grayscale = val.b_bool;
+ p_dec->pf_decode_video = DecodeBlock;
+
msg_Dbg( p_dec, "cinepak decoder started" );
return VLC_SUCCESS;
}
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with whole frames.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
int i_status, i_plane;
uint8_t *p_dst, *p_src;
picture_t *p_pic;
+ block_t *p_block;
+
+ if( !pp_block || !*pp_block ) return NULL;
- i_status = cinepak_decode_frame( p_sys->p_context,
- p_block->i_buffer, p_block->p_buffer );
+ p_block = *pp_block;
+
+ i_status = cinepak_decode_frame( p_sys->p_context, p_block->i_buffer,
+ p_block->p_buffer );
if( i_status < 0 )
{
msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
p_block->i_buffer );
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
- /* Check our vout */
- p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
- p_sys->p_context->i_width,
- p_sys->p_context->i_height,
- VLC_FOURCC('I','4','2','0'),
- p_sys->p_context->i_width
- * VOUT_ASPECT_FACTOR
- / p_sys->p_context->i_height );
- if( !p_sys->p_vout )
- {
- msg_Err( p_dec, "cannot create vout" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
+ p_dec->fmt_out.video.i_width = p_sys->p_context->i_width;
+ p_dec->fmt_out.video.i_height = p_sys->p_context->i_height;
+ p_dec->fmt_out.video.i_aspect = p_sys->p_context->i_width
+ * VOUT_ASPECT_FACTOR / p_sys->p_context->i_height;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
+
+ /* Get a new picture */
+ p_pic = p_dec->pf_vout_buffer_new( p_dec );
- /* Send decoded frame to vout */
- while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+ if( p_pic == NULL )
{
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- {
- block_Release( p_block );
- return VLC_EGENERIC;
- }
- msleep( VOUT_OUTMEM_SLEEP );
+ block_Release( p_block );
+ return NULL;
}
for( i_plane = 0; i_plane < 3; i_plane++ )
}
}
- vout_DatePicture( p_sys->p_vout, p_pic, p_block->i_pts);
- vout_DisplayPicture( p_sys->p_vout, p_pic );
-
+ p_pic->date = p_block->i_pts;
block_Release( p_block );
- return VLC_SUCCESS;
+
+ return p_pic;
}
/*****************************************************************************
- * EndDecoder: theora decoder destruction
+ * CloseDecoder: decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
int i;
msg_Dbg( p_dec, "cinepak decoder stopped" );
- vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
-
for( i = 0; i < 3; i++ )
{
if( p_sys->p_context->p_pix[i] ) free( p_sys->p_context->p_pix[i] );
free( p_sys->p_context );
free( p_sys );
-
- return VLC_SUCCESS;
}
/*****************************************************************************
/*****************************************************************************
- * dts.c: DTS basic parser
+ * dts.c: parse DTS audio sync info and packetize the stream
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: dts.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: dts.c,v 1.5 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Gildas Bazin <gbazin@netcourrier.com>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* memcpy() */
-#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#include <vlc/aout.h>
-#include <vlc/sout.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include "vlc_block_helper.h"
#define DTS_HEADER_SIZE 10
/*
* Input properties
*/
- int i_state;
+ int i_state;
- uint8_t p_header[DTS_HEADER_SIZE];
- int i_header;
-
- mtime_t pts;
-
- int i_frame_size;
+ block_bytestream_t bytestream;
/*
- * Decoder output properties
+ * Common properties
*/
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
- audio_sample_format_t aout_format;
- aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */
+ audio_date_t end_date;
+
+ mtime_t i_pts;
+
+ int i_frame_size, i_bit_rate;
+ unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
+
/* This is very hacky. For DTS over S/PDIF we apparently need to send
* 3 frames at a time. This should likely be moved to the output stage. */
- int i_frames_in_buf;
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
- sout_buffer_t * p_sout_buffer; /* current sout buffer */
+ int i_frames_in_buf;
+ aout_buffer_t *p_aout_buffer; /* current aout buffer being filled */
- /*
- * Common properties
- */
- uint8_t *p_out_buffer; /* output buffer */
- int i_out_buffer; /* position in output buffer */
- audio_date_t end_date;
};
enum {
STATE_NOSYNC,
- STATE_PARTIAL_SYNC,
STATE_SYNC,
STATE_HEADER,
- STATE_DATA
+ STATE_NEXT_SYNC,
+ STATE_GET_DATA,
+ STATE_SEND_DATA
};
/****************************************************************************
****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int OpenPacketizer( vlc_object_t * );
-
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void CloseDecoder ( vlc_object_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
static int SyncInfo ( const byte_t *, unsigned int *, unsigned int *,
unsigned int *, unsigned int *, unsigned int * );
-static int GetOutBuffer ( decoder_t *, uint8_t ** );
-static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
-static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
-static int SendOutBuffer( decoder_t * );
+static uint8_t *GetOutBuffer ( decoder_t *, void ** );
+static aout_buffer_t *GetAoutBuffer( decoder_t * );
+static block_t *GetSoutBuffer( decoder_t * );
/*****************************************************************************
* Module descriptor
vlc_module_begin();
set_description( _("DTS parser") );
set_capability( "decoder", 100 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_submodule();
set_description( _("DTS audio packetizer") );
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
- && p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s',' ')
+ && p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s','b') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- p_dec->p_sys->b_packetizer = VLC_FALSE;
+
+ /* Misc init */
+ p_sys->b_packetizer = VLC_FALSE;
+ p_sys->i_state = STATE_NOSYNC;
+ aout_DateSet( &p_sys->end_date, 0 );
+ p_sys->i_frames_in_buf = 0;
+
+ p_sys->bytestream = block_BytestreamInit( p_dec );
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('d','t','s',' ');
+
+ /* Set callback */
+ p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
return VLC_SUCCESS;
}
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- p_dec->p_sys->i_state = STATE_NOSYNC;
-
- p_dec->p_sys->p_out_buffer = NULL;
- p_dec->p_sys->i_out_buffer = 0;
- aout_DateSet( &p_dec->p_sys->end_date, 0 );
-
- p_dec->p_sys->p_aout = NULL;
- p_dec->p_sys->p_aout_input = NULL;
- p_dec->p_sys->p_aout_buffer = NULL;
- p_dec->p_sys->aout_format.i_format = VLC_FOURCC('d','t','s',' ');
-
- p_dec->p_sys->p_sout_input = NULL;
- p_dec->p_sys->p_sout_buffer = NULL;
- p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
- p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC('d','t','s',' ');
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function is called just after the thread is launched.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int i, i_block_pos = 0;
- mtime_t i_pts = p_block->i_pts;
+ uint8_t p_header[DTS_HEADER_SIZE];
+ uint8_t *p_buf;
+ void *p_out_buffer;
- while( i_block_pos < p_block->i_buffer )
+ if( !pp_block || !*pp_block ) return NULL;
+
+ if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
+ {
+ /* We've just started the stream, wait for the first PTS. */
+ block_Release( *pp_block );
+ return NULL;
+ }
+
+ if( (*pp_block)->b_discontinuity )
+ {
+ p_sys->i_state = STATE_NOSYNC;
+ }
+
+ block_BytestreamPush( &p_sys->bytestream, *pp_block );
+
+ while( 1 )
{
switch( p_sys->i_state )
{
case STATE_NOSYNC:
/* Look for sync dword - should be 0x7ffe8001 */
- while( i_block_pos < p_block->i_buffer &&
- p_block->p_buffer[i_block_pos] != 0x7f )
+ while( block_PeekBytes( &p_sys->bytestream, p_header, 4 )
+ == VLC_SUCCESS )
{
- i_block_pos++;
- }
-
- if( i_block_pos < p_block->i_buffer )
- {
- p_sys->i_state = STATE_PARTIAL_SYNC;
- i_block_pos++;
- p_sys->p_header[0] = 0x7f;
- p_sys->i_header = 1;
- break;
- }
- break;
-
- case STATE_PARTIAL_SYNC:
- /* Get the full 4 sync bytes */
- if( p_sys->i_header < 4 )
- {
- int i_size = __MIN( 4 - p_sys->i_header,
- p_block->i_buffer - i_block_pos );
-
- memcpy( p_sys->p_header + p_sys->i_header,
- p_block->p_buffer + i_block_pos, i_size );
- i_block_pos += i_size;
- p_sys->i_header += i_size;
- }
-
- if( p_sys->i_header < 4 )
- break;
-
- if( p_sys->p_header[0] == 0x7f && p_sys->p_header[1] == 0xfe &&
- p_sys->p_header[2] == 0x80 && p_sys->p_header[3] == 0x01 )
- {
- p_sys->i_state = STATE_SYNC;
- }
- else
- {
- for( i = 1; i < 4; i++ )
+ if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
+ p_header[2] == 0x80 && p_header[3] == 0x01 )
{
- if( p_sys->p_header[i] == 0x7f ) break;
- }
-
- if( p_sys->p_header[i] == 0x7f )
- {
- /* Potential new sync */
- p_sys->i_header -= i;
- memmove( p_sys->p_header, &p_sys->p_header[i],
- p_sys->i_header );
+ p_sys->i_state = STATE_SYNC;
break;
}
+ block_SkipByte( &p_sys->bytestream );
+ }
+ if( p_sys->i_state != STATE_SYNC )
+ {
+ block_BytestreamFlush( &p_sys->bytestream );
- /* retry to sync*/
- p_sys->i_state = STATE_NOSYNC;
+ /* Need more data */
+ return NULL;
}
- break;
case STATE_SYNC:
/* New frame, set the Presentation Time Stamp */
- p_sys->pts = i_pts; i_pts = 0;
- if( p_sys->pts != 0 &&
- p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+ if( p_sys->i_pts != 0 &&
+ p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->end_date, p_sys->pts );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
p_sys->i_state = STATE_HEADER;
- break;
case STATE_HEADER:
/* Get DTS frame header (DTS_HEADER_SIZE bytes) */
- if( p_sys->i_header < DTS_HEADER_SIZE )
+ if( block_PeekBytes( &p_sys->bytestream, p_header,
+ DTS_HEADER_SIZE ) != VLC_SUCCESS )
{
- int i_size = __MIN( DTS_HEADER_SIZE - p_sys->i_header,
- p_block->i_buffer - i_block_pos );
-
- memcpy( p_sys->p_header + p_sys->i_header,
- p_block->p_buffer + i_block_pos, i_size );
- i_block_pos += i_size;
- p_sys->i_header += i_size;
+ /* Need more data */
+ return NULL;
}
- if( p_sys->i_header < DTS_HEADER_SIZE )
+ /* Check if frame is valid and get frame info */
+ p_sys->i_frame_size = SyncInfo( p_header,
+ &p_sys->i_channels,
+ &p_sys->i_channels_conf,
+ &p_sys->i_rate,
+ &p_sys->i_bit_rate,
+ &p_sys->i_frame_length );
+ if( !p_sys->i_frame_size )
+ {
+ msg_Dbg( p_dec, "emulated sync word" );
+ block_SkipByte( &p_sys->bytestream );
+ p_sys->i_state = STATE_NOSYNC;
break;
+ }
+ p_sys->i_state = STATE_NEXT_SYNC;
- if( GetOutBuffer( p_dec, &p_sys->p_out_buffer )
+ case STATE_NEXT_SYNC:
+ /* TODO: If pp_block == NULL, flush the buffer without checking the
+ * next sync word */
+
+ /* Check if next expected frame contains the sync word */
+ if( block_PeekOffsetBytes( &p_sys->bytestream,
+ p_sys->i_frame_size, p_header, 4 )
!= VLC_SUCCESS )
{
- block_Release( p_block );
- return VLC_EGENERIC;
+ /* Need more data */
+ return NULL;
}
- if( !p_sys->p_out_buffer )
+ if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
+ p_header[2] == 0x80 && p_header[3] == 0x01 )
{
+ msg_Dbg( p_dec, "emulated sync word "
+ "(no sync on following frame)" );
p_sys->i_state = STATE_NOSYNC;
+ block_SkipByte( &p_sys->bytestream );
break;
}
-
- memcpy( p_sys->p_out_buffer, p_sys->p_header, DTS_HEADER_SIZE );
- p_sys->i_out_buffer = DTS_HEADER_SIZE;
- p_sys->i_state = STATE_DATA;
+ p_sys->i_state = STATE_SEND_DATA;
break;
- case STATE_DATA:
- /* Copy the whole DTS frame into the aout buffer */
- if( p_sys->i_out_buffer < p_sys->i_frame_size )
+ case STATE_GET_DATA:
+ /* Make sure we have enough data.
+ * (Not useful if we went through NEXT_SYNC) */
+ if( block_WaitBytes( &p_sys->bytestream,
+ p_sys->i_frame_size ) != VLC_SUCCESS )
{
- int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer,
- p_block->i_buffer - i_block_pos );
-
- memcpy( p_sys->p_out_buffer + p_sys->i_out_buffer,
- p_block->p_buffer + i_block_pos, i_size );
- i_block_pos += i_size;
- p_sys->i_out_buffer += i_size;
+ /* Need more data */
+ return NULL;
}
+ p_sys->i_state = STATE_SEND_DATA;
- if( p_sys->i_out_buffer < p_sys->i_frame_size )
- break; /* Need more data */
+ case STATE_SEND_DATA:
+ if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
+ {
+ //p_dec->b_error = VLC_TRUE;
+ return NULL;
+ }
- SendOutBuffer( p_dec );
+ /* Copy the whole frame into the buffer. When we reach this point
+ * we already know we have enough data available. */
+ block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
- p_sys->i_state = STATE_NOSYNC;
- break;
- }
- }
+ /* Make sure we don't reuse the same pts twice */
+ if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
- block_Release( p_block );
- return VLC_SUCCESS;
-}
+ /* So p_block doesn't get re-added several times */
+ *pp_block = block_BytestreamPop( &p_sys->bytestream );
-/*****************************************************************************
- * EndDecoder: clean up the decoder
- *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
-{
- if( p_dec->p_sys->p_aout_input != NULL )
- {
- if( p_dec->p_sys->p_aout_buffer )
- {
- aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
- p_dec->p_sys->p_aout_input,
- p_dec->p_sys->p_aout_buffer );
- }
+ p_sys->i_state = STATE_NOSYNC;
- aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
- }
+ if( !p_sys->b_packetizer )
+ {
+ if( p_sys->i_frames_in_buf != 3 ) return NULL;
+ else
+ {
+ p_sys->i_frames_in_buf = 0;
+ p_sys->p_aout_buffer = 0;
+ }
+ }
- if( p_dec->p_sys->p_sout_input != NULL )
- {
- if( p_dec->p_sys->p_sout_buffer )
- {
- sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
- p_dec->p_sys->p_sout_buffer );
+ return p_out_buffer;
}
-
- sout_InputDelete( p_dec->p_sys->p_sout_input );
}
- free( p_dec->p_sys );
-
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
- * GetOutBuffer:
+ * CloseDecoder: clean up the decoder
*****************************************************************************/
-static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t*)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_ret;
- if( p_sys->b_packetizer )
- {
- i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
- *pp_out_buffer =
- p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
- }
- else
- {
- i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
- if( p_sys->i_frames_in_buf == 1 )
- *pp_out_buffer = p_sys->p_aout_buffer ?
- p_sys->p_aout_buffer->p_buffer : NULL;
- else
- *pp_out_buffer = p_sys->p_aout_buffer ?
- p_sys->p_aout_buffer->p_buffer + p_sys->i_frame_size *
- (p_sys->i_frames_in_buf - 1) : NULL;
- }
+ block_BytestreamRelease( &p_sys->bytestream );
- return i_ret;
+ free( p_sys );
}
/*****************************************************************************
- * GetAoutBuffer:
+ * GetOutBuffer:
*****************************************************************************/
-static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
{
- int i_bit_rate;
- unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
-
decoder_sys_t *p_sys = p_dec->p_sys;
+ uint8_t *p_buf;
- /* Check if frame is valid and get frame info */
- p_sys->i_frame_size = SyncInfo( p_sys->p_header,
- &i_channels, &i_channels_conf,
- &i_rate, &i_bit_rate, &i_frame_length );
-
- if( !p_sys->i_frame_size )
+ if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
{
- msg_Warn( p_dec, "dts syncinfo failed" );
- *pp_buffer = NULL;
- return VLC_SUCCESS;
- }
+ msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
+ p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
- if( p_sys->p_aout_input != NULL && ( p_sys->aout_format.i_rate != i_rate
- || p_sys->aout_format.i_original_channels != i_channels_conf
- || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
- {
- /* Parameters changed - this should not happen. */
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- p_sys->p_aout_input = NULL;
+ aout_DateInit( &p_sys->end_date, p_sys->i_rate );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
- /* Creating the audio input if not created yet. */
- if( p_sys->p_aout_input == NULL )
- {
- p_sys->aout_format.i_rate = i_rate;
- p_sys->aout_format.i_original_channels = i_channels_conf;
- p_sys->aout_format.i_physical_channels
- = i_channels_conf & AOUT_CHAN_PHYSMASK;
- p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size;
- p_sys->aout_format.i_frame_length = i_frame_length;
- aout_DateInit( &p_sys->end_date, i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
- p_sys->i_frames_in_buf = 3;
- p_sys->p_aout_input = aout_DecNew( p_dec,
- &p_sys->p_aout,
- &p_sys->aout_format );
-
- if ( p_sys->p_aout_input == NULL )
- {
- *pp_buffer = NULL;
- return VLC_SUCCESS;
- }
- }
+ p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
+ p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+ p_dec->fmt_out.audio.i_bitrate = p_sys->i_bit_rate;
+ p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
+ p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
+
+ p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
- if( !aout_DateGet( &p_sys->end_date ) )
+ if( p_sys->b_packetizer )
{
- /* We've just started the stream, wait for the first PTS. */
- *pp_buffer = NULL;
- return VLC_SUCCESS;
+ block_t *p_sout_buffer = GetSoutBuffer( p_dec );
+ p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
+ *pp_out_buffer = p_sout_buffer;
}
-
- if( p_sys->i_frames_in_buf == 3 )
+ else
{
- p_sys->i_frames_in_buf = 0;
- *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
- i_frame_length * 3 );
- if( *pp_buffer == NULL )
+ if( !p_sys->i_frames_in_buf )
{
- return VLC_SUCCESS;
+ p_sys->p_aout_buffer = GetAoutBuffer( p_dec );
}
-
- (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
- (*pp_buffer)->end_date =
- aout_DateIncrement( &p_sys->end_date, i_frame_length * 3 );
+ p_buf = p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer +
+ p_sys->i_frames_in_buf * p_sys->i_frame_size : NULL;
+ *pp_out_buffer = p_sys->p_aout_buffer;
}
p_sys->i_frames_in_buf++;
- return VLC_SUCCESS;
+ return p_buf;
}
/*****************************************************************************
- * GetSoutBuffer:
+ * GetAoutBuffer:
*****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
{
- int i_bit_rate;
- unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
-
decoder_sys_t *p_sys = p_dec->p_sys;
+ aout_buffer_t *p_buf;
- /* Check if frame is valid and get frame info */
- p_sys->i_frame_size = SyncInfo( p_sys->p_header,
- &i_channels, &i_channels_conf,
- &i_rate, &i_bit_rate, &i_frame_length );
-
- if( !p_sys->i_frame_size )
- {
- msg_Warn( p_dec, "dts syncinfo failed" );
- *pp_buffer = NULL;
- return VLC_SUCCESS;
- }
-
- if( p_sys->p_sout_input != NULL &&
- ( p_sys->sout_format.i_sample_rate != (int)i_rate
- || p_sys->sout_format.i_channels != (int)i_channels ) )
- {
- /* Parameters changed - this should not happen. */
- }
-
- /* Creating the sout input if not created yet. */
- if( p_sys->p_sout_input == NULL )
- {
- p_sys->sout_format.i_sample_rate = i_rate;
- p_sys->sout_format.i_channels = i_channels;
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = i_bit_rate;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
-
- aout_DateInit( &p_sys->end_date, i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
-
- p_sys->p_sout_input = sout_InputNew( p_dec,
- &p_sys->sout_format );
-
- if( p_sys->p_sout_input == NULL )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- *pp_buffer = NULL;
- return VLC_EGENERIC;
- }
- msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
- i_channels, i_rate, i_bit_rate );
- }
-
- if( !aout_DateGet( &p_sys->end_date ) )
- {
- /* We've just started the stream, wait for the first PTS. */
- *pp_buffer = NULL;
- return VLC_SUCCESS;
- }
-
- *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
- p_sys->i_frame_size );
- if( *pp_buffer == NULL )
- {
- return VLC_SUCCESS;
- }
-
- (*pp_buffer)->i_pts =
- (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
+ p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length * 3 );
+ if( p_buf == NULL ) return NULL;
- (*pp_buffer)->i_length =
- aout_DateIncrement( &p_sys->end_date, i_frame_length )
- - (*pp_buffer)->i_pts;
+ p_buf->start_date = aout_DateGet( &p_sys->end_date );
+ p_buf->end_date =
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length * 3 );
- return VLC_SUCCESS;
+ return p_buf;
}
/*****************************************************************************
- * SendOutBuffer:
+ * GetSoutBuffer:
*****************************************************************************/
-static int SendOutBuffer( decoder_t *p_dec )
+static block_t *GetSoutBuffer( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
- if( p_sys->b_packetizer )
- {
- sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
- p_sys->p_sout_buffer = NULL;
- }
- else if( p_sys->i_frames_in_buf == 3 )
- {
- /* We have all we need, send the buffer to the aout core. */
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
- p_sys->p_aout_buffer );
- p_sys->p_aout_buffer = NULL;
- }
+ p_block = block_New( p_dec, p_sys->i_frame_size );
+ if( p_block == NULL ) return NULL;
- return VLC_SUCCESS;
+ p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
+
+ p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+ p_sys->i_frame_length ) - p_block->i_pts;
+
+ return p_block;
}
/*****************************************************************************
* dv.c: a decoder for DV video
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: dv.c,v 1.5 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: dv.c,v 1.6 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
{
decoder_t *p_dec = (decoder_t*)p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','s','d') )
{
return VLC_EGENERIC;
}
* dvbsub.c : DVB subtitles decoder thread
*****************************************************************************
* Copyright (C) 2003 ANEVIA
- * $Id: dvbsub.c,v 1.2 2003/11/06 19:35:05 nitrox Exp $
+ * $Id: dvbsub.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Damien LUCAS <damien.lucas@anevia.com>
*
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*) p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','v','b','s') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
{
return VLC_EGENERIC;
}
* decoder.c: AAC decoder using libfaad2
*****************************************************************************
* Copyright (C) 2001, 2003 VideoLAN
- * $Id: faad.c,v 1.3 2003/11/05 01:47:40 fenrir Exp $
+ * $Id: faad.c,v 1.4 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* Module descriptor
*****************************************************************************/
static int Open( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
vlc_module_begin();
set_description( _("AAC audio decoder (using libfaad2)") );
set_capability( "decoder", 60 );
- set_callbacks( Open, NULL );
+ set_callbacks( Open, CloseDecoder );
vlc_module_end();
/****************************************************************************
* Local prototypes
****************************************************************************/
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
struct decoder_sys_t
{
/* faad handler */
faacDecHandle *hfaad;
- /* audio output */
- audio_sample_format_t output_format;
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
-
/* samples */
- audio_date_t date;
+ audio_date_t date;
/* temporary buffer */
- uint8_t *p_buffer;
- int i_buffer;
- int i_buffer_size;
+ uint8_t *p_buffer;
+ int i_buffer;
+ int i_buffer_size;
};
-/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
- decoder_t *p_dec = (decoder_t*)p_this;
-
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
- {
- return VLC_EGENERIC;
- }
-
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
- p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
-
- return VLC_SUCCESS;
-}
-
static unsigned int pi_channels_maps[7] =
{
0,
AOUT_CHAN_CENTER,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT |
+ AOUT_CHAN_REARRIGHT,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
+ AOUT_CHAN_REARRIGHT,
/* FIXME */
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
+ AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER
};
/*****************************************************************************
- * InitDecoder:
+ * OpenDecoder: probe the decoder and return score
*****************************************************************************/
-static int InitDecoder ( decoder_t *p_dec )
+static int Open( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t*)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- WAVEFORMATEX wf, *p_wf;
faacDecConfiguration *cfg;
- if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','4','a') )
{
- p_wf = &wf;
- memset( p_wf, 0, sizeof( WAVEFORMATEX ) );
+ return VLC_EGENERIC;
+ }
+
+ /* Allocate the memory needed to store the decoder's structure */
+ if( ( p_dec->p_sys = p_sys =
+ (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
+ {
+ msg_Err( p_dec, "out of memory" );
+ return VLC_EGENERIC;
}
/* Open a faad context */
return VLC_EGENERIC;
}
- if( p_wf->cbSize > 0 )
+ /* Misc init */
+ aout_DateSet( &p_sys->date, 0 );
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
+ p_dec->pf_decode_audio = DecodeBlock;
+
+ if( p_dec->fmt_in.i_extra > 0 )
{
/* We have a decoder config so init the handle */
- unsigned long i_rate;
- unsigned char i_channels;
+ unsigned long i_rate;
+ unsigned char i_channels;
- if( faacDecInit2( p_sys->hfaad,
- (uint8_t*)&p_wf[1], p_wf->cbSize,
+ if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
+ p_dec->fmt_in.i_extra,
&i_rate, &i_channels ) < 0 )
{
return VLC_EGENERIC;
}
- p_sys->output_format.i_rate = i_rate;
- p_sys->output_format.i_physical_channels =
- p_sys->output_format.i_original_channels =
- pi_channels_maps[i_channels];
+ p_dec->fmt_out.audio.i_rate = i_rate;
+ p_dec->fmt_out.audio.i_channels = i_channels;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
+ pi_channels_maps[i_channels];
+
+ aout_DateInit( &p_sys->date, i_rate );
}
else
{
/* Will be initalised from first frame */
- p_sys->output_format.i_rate = 0;
- p_sys->output_format.i_physical_channels =
- p_sys->output_format.i_original_channels = 0;
+ p_dec->fmt_out.audio.i_rate = 0;
+ p_dec->fmt_out.audio.i_channels = 0;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels = 0;
}
- p_sys->output_format.i_format = VLC_FOURCC('f','l','3','2');
-
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = NULL;
- /* set the faad config */
+ /* Set the faad config */
cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
cfg->outputFormat = FAAD_FMT_FLOAT;
faacDecSetConfiguration( p_sys->hfaad, cfg );
}
/*****************************************************************************
- * InitDecoder:
+ * DecodeBlock:
*****************************************************************************/
-static int RunDecoder ( decoder_t *p_dec, block_t *p_block )
+static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
- int i_used = 0;
- mtime_t i_pts = p_block->i_pts;
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
/* Append the block to the temporary buffer */
if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
{
- p_sys->i_buffer_size += p_block->i_buffer;
+ p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
}
- memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer, p_block->i_buffer );
- p_sys->i_buffer += p_block->i_buffer;
- if( p_sys->output_format.i_rate == 0 )
+ if( p_block->i_buffer )
+ {
+ memcpy( &p_sys->p_buffer[p_sys->i_buffer],
+ p_block->p_buffer, p_block->i_buffer );
+ p_sys->i_buffer += p_block->i_buffer;
+ p_block->i_buffer = 0;
+ }
+
+ if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
{
- unsigned long i_rate;
- unsigned char i_channels;
+ unsigned long i_rate;
+ unsigned char i_channels;
/* Init faad with the first frame */
if( faacDecInit( p_sys->hfaad,
&i_rate, &i_channels ) < 0 )
{
block_Release( p_block );
- return VLC_EGENERIC;
+ return NULL;
}
- p_sys->output_format.i_rate = i_rate;
- p_sys->output_format.i_physical_channels =
- p_sys->output_format.i_original_channels =
- pi_channels_maps[i_channels];
+
+ p_dec->fmt_out.audio.i_rate = i_rate;
+ p_dec->fmt_out.audio.i_channels = i_channels;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
+ pi_channels_maps[i_channels];
+
+ aout_DateInit( &p_sys->date, i_rate );
+ }
+
+ if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
+ {
+ aout_DateSet( &p_sys->date, p_block->i_pts );
+ }
+ else if( !aout_DateGet( &p_sys->date ) )
+ {
+ /* We've just started the stream, wait for the first PTS. */
+ block_Release( p_block );
+ p_sys->i_buffer = 0;
+ return NULL;
}
/* Decode all data */
- while( i_used < p_sys->i_buffer )
+ if( p_sys->i_buffer )
{
void *samples;
faacDecFrameInfo frame;
- aout_buffer_t *out;
+ aout_buffer_t *p_out;
samples = faacDecDecode( p_sys->hfaad, &frame,
- &p_sys->p_buffer[i_used], p_sys->i_buffer - i_used );
+ p_sys->p_buffer, p_sys->i_buffer );
if( frame.error > 0 )
{
msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );
- /* flush the buffer */
+
+ /* Flush the buffer */
p_sys->i_buffer = 0;
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
+
if( frame.channels <= 0 || frame.channels > 6 )
{
msg_Warn( p_dec, "invalid channels count" );
- /* flush the buffer */
+
+ /* Flush the buffer */
p_sys->i_buffer = 0;
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
+
if( frame.samples <= 0 )
{
msg_Warn( p_dec, "decoded zero samples" );
- /* flush the buffer */
+
+ /* Flush the buffer */
p_sys->i_buffer = 0;
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
- /* we have decoded a valid frame */
- /* msg_Dbg( p_dec, "consumed %d for %dHz %dc %lld", frame.bytesconsumed, frame.samplerate, frame.channels, i_pts ); */
- i_used += frame.bytesconsumed;
-
-
- /* create/recreate the output */
- if( p_sys->p_aout_input &&
- ( p_sys->output_format.i_original_channels != pi_channels_maps[frame.channels] ||
- p_sys->output_format.i_rate != frame.samplerate ) )
+ /* We decoded a valid frame */
+ if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
{
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- p_sys->p_aout_input = NULL;
+ aout_DateInit( &p_sys->date, frame.samplerate );
+ aout_DateSet( &p_sys->date, p_block->i_pts );
}
+ p_block->i_pts = 0; /* PTS is valid only once */
- if( p_sys->p_aout_input == NULL )
- {
- p_sys->output_format.i_physical_channels =
- p_sys->output_format.i_original_channels = pi_channels_maps[frame.channels];
- p_sys->output_format.i_rate = frame.samplerate;
-
- aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
- aout_DateSet( &p_sys->date, 0 );
-
- p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->output_format );
- }
+ p_dec->fmt_out.audio.i_rate = frame.samplerate;
+ p_dec->fmt_out.audio.i_channels = frame.channels;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
+ pi_channels_maps[frame.channels];
- if( p_sys->p_aout_input == NULL )
+ p_out = p_dec->pf_aout_buffer_new( p_dec,
+ frame.samples / frame.channels );
+ if( p_out == NULL )
{
- msg_Err( p_dec, "cannot create aout" );
+ p_sys->i_buffer = 0;
block_Release( p_block );
- return VLC_EGENERIC;
+ return NULL;
}
- if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->date ) )
- {
- aout_DateSet( &p_sys->date, i_pts );
- }
- else if( !aout_DateGet( &p_sys->date ) )
- {
- /* Wait for a dated packet */
- msg_Dbg( p_dec, "no date" );
- p_sys->i_buffer = 0;
- return VLC_SUCCESS;
- }
- i_pts = 0; /* PTS is valid only once */
+ p_out->start_date = aout_DateGet( &p_sys->date );
+ p_out->end_date = aout_DateIncrement( &p_sys->date,
+ frame.samples / frame.channels );
+
+ memcpy( p_out->p_buffer, samples, p_out->i_nb_bytes );
- if( ( out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
- frame.samples / frame.channels ) ) == NULL )
+ p_sys->i_buffer -= frame.bytesconsumed;
+ if( p_sys->i_buffer > 0 )
{
- msg_Err( p_dec, "cannot get a new buffer" );
- block_Release( p_block );
- return VLC_EGENERIC;
+ memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],
+ p_sys->i_buffer );
}
- out->start_date = aout_DateGet( &p_sys->date );
- out->end_date = aout_DateIncrement( &p_sys->date,
- frame.samples / frame.channels );
- memcpy( out->p_buffer, samples, out->i_nb_bytes );
-
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
- }
- p_sys->i_buffer -= i_used;
- if( p_sys->i_buffer > 0 )
- {
- memmove( &p_sys->p_buffer[0], &p_sys->p_buffer[i_used], p_sys->i_buffer );
+ return p_out;
}
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
- * InitDecoder:
+ * CloseDecoder:
*****************************************************************************/
-static int EndDecoder ( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_sys->p_aout_input )
- {
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
-
faacDecClose( p_sys->hfaad );
free( p_sys );
-
- return VLC_SUCCESS;
}
-
-
-
* audio.c: audio decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
- * $Id: audio.c,v 1.21 2003/10/27 10:00:40 gbazin Exp $
+ * $Id: audio.c,v 1.22 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
#include <string.h>
#include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/aout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* getpid() */
-#endif
-
-#ifdef HAVE_SYS_TIMES_H
-# include <sys/times.h>
-#endif
-
#include "codecs.h"
#include "aout_internal.h"
/*
* Output properties
*/
- aout_instance_t *p_aout;
- aout_input_t *p_aout_input;
audio_sample_format_t aout_format;
audio_date_t end_date;
};
AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
{
decoder_sys_t *p_sys;
- WAVEFORMATEX wf, *p_wf;
/* Allocate the memory needed to store the decoder's structure */
if( ( p_dec->p_sys = p_sys =
p_dec->p_sys->i_codec_id = i_codec_id;
p_dec->p_sys->psz_namecodec = psz_namecodec;
- if( ( p_wf = p_dec->p_fifo->p_waveformatex ) == NULL )
- {
- msg_Warn( p_dec, "audio informations missing" );
- p_wf = &wf;
- memset( p_wf, 0, sizeof( WAVEFORMATEX ) );
- }
-
/* ***** Fill p_context with init values ***** */
- p_sys->p_context->sample_rate = p_wf->nSamplesPerSec;
- p_sys->p_context->channels = p_wf->nChannels;
- p_sys->p_context->block_align = p_wf->nBlockAlign;
- p_sys->p_context->bit_rate = p_wf->nAvgBytesPerSec * 8;
+ p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
+ p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;
+ p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
+ p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
- if( ( p_sys->p_context->extradata_size = p_wf->cbSize ) > 0 )
+ if( ( p_sys->p_context->extradata_size = p_dec->fmt_in.i_extra ) > 0 )
{
p_sys->p_context->extradata =
- malloc( p_wf->cbSize + FF_INPUT_BUFFER_PADDING_SIZE );
- memcpy( p_sys->p_context->extradata, &p_wf[1], p_wf->cbSize);
- memset( &((uint8_t*)p_sys->p_context->extradata)[p_wf->cbSize], 0,
+ malloc( p_dec->fmt_in.i_extra + FF_INPUT_BUFFER_PADDING_SIZE );
+ memcpy( p_sys->p_context->extradata,
+ p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+ memset( p_sys->p_context->extradata + p_dec->fmt_in.i_extra, 0,
FF_INPUT_BUFFER_PADDING_SIZE );
}
p_sys->p_output = malloc( 3 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = NULL;
-
aout_DateSet( &p_sys->end_date, 0 );
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
+
return VLC_SUCCESS;
}
/*****************************************************************************
* DecodeAudio: Called to decode one frame
*****************************************************************************/
-int E_( DecodeAudio )( decoder_t *p_dec, block_t *p_block )
+aout_buffer_t *E_( DecodeAudio )( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- aout_buffer_t *p_aout_buffer;
- mtime_t i_pts;
+ int i_used, i_output, i_samples;
+ uint8_t *p_samples;
+ aout_buffer_t *p_buffer;
+ block_t *p_block;
+
+ if( !pp_block || !*pp_block ) return NULL;
- uint8_t *p_buffer, *p_samples;
- int i_buffer, i_samples;
+ p_block = *pp_block;
if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
{
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
- i_pts = p_block->i_pts;
- i_buffer = p_block->i_buffer;
- p_buffer = p_block->p_buffer;
-
- while( i_buffer )
+ if( !p_block->i_buffer )
{
- int i_used, i_output;
+ block_Release( p_block );
+ return NULL;
+ }
- i_used = avcodec_decode_audio( p_sys->p_context,
- (int16_t*)p_sys->p_output, &i_output,
- p_buffer, i_buffer );
+ i_used = avcodec_decode_audio( p_sys->p_context,
+ (int16_t*)p_sys->p_output, &i_output,
+ p_block->p_buffer, p_block->i_buffer );
+
+ if( i_used < 0 )//|| i_output == 0 )
+ {
if( i_used < 0 )
- {
- msg_Warn( p_dec, "cannot decode one frame (%d bytes)", i_buffer );
- break;
- }
-
- i_buffer -= i_used;
- p_buffer += i_used;
-
- if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
- {
- msg_Warn( p_dec, "invalid channels count %d",
- p_sys->p_context->channels );
- break;
- }
-
- /* **** First check if we have a valid output **** */
- if( p_sys->p_aout_input == NULL ||
- p_sys->aout_format.i_original_channels !=
- pi_channels_maps[p_sys->p_context->channels] )
- {
- if( p_sys->p_aout_input != NULL )
- {
- /* **** Delete the old **** */
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
-
- /* **** Create a new audio output **** */
- p_sys->aout_format.i_format = AOUT_FMT_S16_NE;
- p_sys->aout_format.i_rate = p_sys->p_context->sample_rate;
- p_sys->aout_format.i_physical_channels =
- p_sys->aout_format.i_original_channels =
- pi_channels_maps[p_sys->p_context->channels];
-
- aout_DateInit( &p_sys->end_date, p_sys->aout_format.i_rate );
- p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
- &p_sys->aout_format );
- }
-
- if( !p_sys->p_aout_input )
- {
- msg_Err( p_dec, "cannot create audio output" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
-
- if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
- {
- aout_DateSet( &p_sys->end_date, i_pts );
- i_pts = 0;
- }
-
- /* **** Now we can output these samples **** */
- i_samples = i_output / 2 / p_sys->p_context->channels;
-
- p_samples = p_sys->p_output;
- while( i_samples > 0 )
- {
- int i_smaller_samples;
-
- i_smaller_samples = __MIN( 8000, i_samples );
-
- p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout,
- p_sys->p_aout_input,
- i_smaller_samples );
- if( !p_aout_buffer )
- {
- msg_Err( p_dec, "cannot get aout buffer" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
-
- p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
- p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
- i_smaller_samples );
- memcpy( p_aout_buffer->p_buffer, p_samples,
- p_aout_buffer->i_nb_bytes );
-
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
-
- p_samples += i_smaller_samples * 2 * p_sys->p_context->channels;
- i_samples -= i_smaller_samples;
- }
+ msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
+ p_block->i_buffer );
+
+ block_Release( p_block );
+ return NULL;
}
- block_Release( p_block );
- return VLC_SUCCESS;
+ p_block->i_buffer -= i_used;
+ p_block->p_buffer += i_used;
+
+ if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
+ {
+ msg_Warn( p_dec, "invalid channels count %d",
+ p_sys->p_context->channels );
+ block_Release( p_block );
+ return NULL;
+ }
+
+ if( p_dec->fmt_out.audio.i_rate != p_sys->p_context->sample_rate )
+ {
+ aout_DateInit( &p_sys->end_date, p_sys->p_context->sample_rate );
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
+ }
+
+ /* **** Set audio output parameters **** */
+ p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
+ p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
+ p_dec->fmt_out.audio.i_original_channels =
+ p_dec->fmt_out.audio.i_physical_channels =
+ pi_channels_maps[p_sys->p_context->channels];
+
+ if( p_block->i_pts != 0 &&
+ p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
+ {
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
+ p_block->i_pts = 0;
+ }
+
+ /* **** Now we can output these samples **** */
+ i_samples = i_output / 2 / p_sys->p_context->channels;
+ p_samples = p_sys->p_output;
+
+ p_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples );
+ if( !p_buffer )
+ {
+ msg_Err( p_dec, "cannot get aout buffer" );
+ block_Release( p_block );
+ return NULL;
+ }
+
+ p_buffer->start_date = aout_DateGet( &p_sys->end_date );
+ p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
+
+ memcpy( p_buffer->p_buffer, p_samples, p_buffer->i_nb_bytes );
+
+ return p_buffer;
}
/*****************************************************************************
decoder_sys_t *p_sys = p_dec->p_sys;
if( p_sys->p_output ) free( p_sys->p_output );
-
- if( p_sys->p_aout_input )
- {
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
}
* encoder.c: video and audio encoder using the ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: encoder.c,v 1.6 2003/11/05 23:32:31 hartman Exp $
+ * $Id: encoder.c,v 1.7 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-int E_(OpenVideoEncoder) ( vlc_object_t * );
-void E_(CloseVideoEncoder)( vlc_object_t * );
-
-int E_(OpenAudioEncoder) ( vlc_object_t * );
-void E_(CloseAudioEncoder)( vlc_object_t * );
+int E_(OpenEncoder) ( vlc_object_t * );
+void E_(CloseEncoder)( vlc_object_t * );
static block_t *EncodeVideo( encoder_t *, picture_t * );
static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
};
/*****************************************************************************
- * OpenVideoEncoder: probe the encoder
+ * OpenEncoder: probe the encoder
*****************************************************************************/
-int E_(OpenVideoEncoder)( vlc_object_t *p_this )
+int E_(OpenEncoder)( vlc_object_t *p_this )
{
encoder_t *p_enc = (encoder_t *)p_this;
encoder_sys_t *p_sys = p_enc->p_sys;
- AVCodecContext *p_context;
+ AVCodecContext *p_context;
AVCodec *p_codec;
int i_codec_id, i_cat;
char *psz_namecodec;
- if( !E_(GetFfmpegCodec)( p_enc->i_fourcc, &i_cat, &i_codec_id,
+ if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
&psz_namecodec ) )
{
return VLC_EGENERIC;
}
- if( i_cat != VIDEO_ES )
+ if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
{
msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
return VLC_EGENERIC;
}
+ if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
+ {
+ msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
+ return VLC_EGENERIC;
+ }
+
/* Initialization must be done before avcodec_find_decoder() */
E_(InitLibavcodec)(p_this);
p_enc->p_sys = p_sys;
p_sys->p_codec = p_codec;
- p_enc->pf_header = NULL;
p_enc->pf_encode_video = EncodeVideo;
- p_enc->format.video.i_chroma = VLC_FOURCC('I','4','2','0');
+ p_enc->pf_encode_audio = EncodeAudio;
- if( p_enc->i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
- p_enc->i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
+ p_sys->p_buffer_out = NULL;
+ p_sys->p_buffer = NULL;
+
+ p_sys->p_context = p_context = avcodec_alloc_context();
+
+ /* Set CPU capabilities */
+#ifdef HAVE_MMX
+ p_context->dsp_mask = 0;
+ if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
+ {
+ p_context->dsp_mask &= FF_MM_MMX;
+ }
+ if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
+ {
+ p_context->dsp_mask &= FF_MM_MMXEXT;
+ }
+ if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
+ {
+ p_context->dsp_mask &= FF_MM_3DNOW;
+ }
+ if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE )
{
- p_enc->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
+ p_context->dsp_mask &= FF_MM_SSE;
+ p_context->dsp_mask &= FF_MM_SSE2; /* FIXME */
}
+ /* Hack to make sure everything can be disabled **/
+ p_context->dsp_mask &= (FF_MM_FORCE >> 1);
+#endif
- p_sys->p_context = p_context = avcodec_alloc_context();
- p_context->width = p_enc->format.video.i_width;
- p_context->height = p_enc->format.video.i_height;
- p_context->bit_rate = p_enc->i_bitrate;
+ /* Make sure we get extradata filled by the encoder */
+ p_context->extradata_size = 0;
+ p_context->extradata = NULL;
+ p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ if( p_enc->fmt_in.i_cat == VIDEO_ES )
+ {
+ p_context->width = p_enc->fmt_in.video.i_width;
+ p_context->height = p_enc->fmt_in.video.i_height;
- p_context->frame_rate = p_enc->i_frame_rate;
+ p_context->frame_rate = p_enc->fmt_in.video.i_frame_rate;
#if LIBAVCODEC_BUILD >= 4662
- p_context->frame_rate_base= p_enc->i_frame_rate_base;
+ p_context->frame_rate_base= p_enc->fmt_in.video.i_frame_rate_base;
#endif
#if LIBAVCODEC_BUILD >= 4687
- p_context->sample_aspect_ratio =
- av_d2q( p_enc->i_aspect * p_context->height / p_context->width /
- VOUT_ASPECT_FACTOR, 255 );
+ p_context->sample_aspect_ratio =
+ av_d2q( p_enc->fmt_in.video.i_aspect * p_context->height /
+ p_context->width / VOUT_ASPECT_FACTOR, 255 );
#else
- p_context->aspect_ratio = ((float)p_enc->i_aspect) / VOUT_ASPECT_FACTOR;
+ p_context->aspect_ratio = ((float)p_enc->fmt_in.video.i_aspect) /
+ VOUT_ASPECT_FACTOR;
#endif
- p_context->gop_size = p_enc->i_key_int >= 0 ? p_enc->i_key_int : 50;
+ p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
+
+ /* Ffmpeg does handle the conversion itself */
+ //p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
+ }
+ else if( p_enc->fmt_in.i_cat == AUDIO_ES )
+ {
+ p_enc->fmt_in.i_codec = AOUT_FMT_S16_NE;
+ p_context->bit_rate = p_enc->fmt_out.i_bitrate;
+ p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
+ p_context->channels = p_enc->fmt_in.audio.i_channels;
+ p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
+ p_sys->p_buffer = malloc( p_sys->i_frame_size );
+ p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
+ }
+
+ /* Misc parameters */
+ p_context->gop_size = p_enc->i_key_int > 0 ? p_enc->i_key_int : 50;
p_context->max_b_frames =
__MIN( p_enc->i_b_frames, FF_MAX_B_FRAMES );
p_context->b_frame_strategy = 0;
p_context->b_quant_factor = 2.0;
- if( p_enc->i_vtolerance >= 0 )
+ if( p_enc->i_vtolerance > 0 )
{
p_context->bit_rate_tolerance = p_enc->i_vtolerance;
}
if( i_codec_id == CODEC_ID_RAWVIDEO )
{
- p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->i_fourcc );
+ p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
}
/* Make sure we get extradata filled by the encoder */
p_context->extradata = NULL;
p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
- if( avcodec_open( p_context, p_sys->p_codec ) )
+ if( avcodec_open( p_context, p_codec ) )
{
- msg_Err( p_enc, "cannot open encoder" );
- return VLC_EGENERIC;
+ if( p_enc->fmt_in.i_cat == AUDIO_ES && p_context->channels > 2 )
+ {
+ p_context->channels = 2;
+ p_enc->fmt_in.audio.i_channels = 2; // FIXME
+ if( avcodec_open( p_context, p_codec ) )
+ {
+ msg_Err( p_enc, "cannot open encoder" );
+ return VLC_EGENERIC;
+ }
+ msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
+ }
+ else
+ {
+ msg_Err( p_enc, "cannot open encoder" );
+ return VLC_EGENERIC;
+ }
}
- p_enc->i_extra_data = p_context->extradata_size;
- p_enc->p_extra_data = p_context->extradata;
+ p_enc->fmt_out.i_extra = p_context->extradata_size;
+ p_enc->fmt_out.p_extra = p_context->extradata;
p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
- p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
+ if( p_enc->fmt_in.i_cat == AUDIO_ES )
+ {
+ p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
+ p_sys->p_buffer = malloc( p_sys->i_frame_size );
+ }
+
p_sys->i_last_ref_pts = 0;
p_sys->i_buggy_pts_detect = 0;
+ p_sys->i_samples_delay = 0;
+ p_sys->i_pts = 0;
msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
}
/* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
- if( p_enc->i_fourcc == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
+ if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
frame.pts = p_pict->date;
else
frame.pts = 0;
p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
/* FIXME, 3-2 pulldown is not handled correctly */
- p_block->i_length = I64C(1000000) * p_enc->i_frame_rate_base /
- p_enc->i_frame_rate;
+ p_block->i_length = I64C(1000000) *
+ p_enc->fmt_in.video.i_frame_rate_base /
+ p_enc->fmt_in.video.i_frame_rate;
p_block->i_pts = p_sys->p_context->coded_frame->pts;
if( !p_sys->p_context->delay ||
{
/* Buggy libavcodec which doesn't update coded_frame->pts
* correctly */
- p_block->i_length = I64C(1000000) * p_enc->i_frame_rate_base /
- p_enc->i_frame_rate;
+ p_block->i_length = I64C(1000000) *
+ p_enc->fmt_in.video.i_frame_rate_base /
+ p_enc->fmt_in.video.i_frame_rate;
p_block->i_dts = p_block->i_pts = p_pict->date;
}
return NULL;
}
-/*****************************************************************************
- * CloseVideoEncoder: ffmpeg video encoder destruction
- *****************************************************************************/
-void E_(CloseVideoEncoder)( vlc_object_t *p_this )
-{
- encoder_t *p_enc = (encoder_t *)p_this;
- encoder_sys_t *p_sys = p_enc->p_sys;
-
- avcodec_close( p_sys->p_context );
- free( p_sys->p_context );
- free( p_sys->p_buffer_out );
- free( p_sys );
-}
-
-/*****************************************************************************
- * OpenAudioEncoder: probe the encoder
- *****************************************************************************/
-int E_(OpenAudioEncoder)( vlc_object_t *p_this )
-{
- encoder_t *p_enc = (encoder_t *)p_this;
- encoder_sys_t *p_sys;
- AVCodecContext *p_context;
- AVCodec *p_codec;
- int i_codec_id, i_cat;
- char *psz_namecodec;
-
- if( !E_(GetFfmpegCodec)( p_enc->i_fourcc, &i_cat, &i_codec_id,
- &psz_namecodec ) )
- {
- return VLC_EGENERIC;
- }
-
- if( i_cat != AUDIO_ES )
- {
- msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
- return VLC_EGENERIC;
- }
-
- /* Initialization must be done before avcodec_find_decoder() */
- E_(InitLibavcodec)(p_this);
-
- p_codec = avcodec_find_encoder( i_codec_id );
- if( !p_codec )
- {
- msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
- return VLC_EGENERIC;
- }
-
- /* Allocate the memory needed to store the decoder's structure */
- if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
- {
- msg_Err( p_enc, "out of memory" );
- return VLC_EGENERIC;
- }
- p_enc->p_sys = p_sys;
- p_sys->p_codec = p_codec;
-
- p_enc->pf_header = NULL;
- p_enc->pf_encode_audio = EncodeAudio;
- p_enc->format.audio.i_format = VLC_FOURCC('s','1','6','n');
-
- p_sys->p_context = p_context = avcodec_alloc_context();
- p_context->bit_rate = p_enc->i_bitrate;
- p_context->sample_rate = p_enc->format.audio.i_rate;
- p_context->channels =
- aout_FormatNbChannels( &p_enc->format.audio );
-
- /* Make sure we get extradata filled by the encoder */
- p_context->extradata_size = 0;
- p_context->extradata = NULL;
- p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
- if( avcodec_open( p_context, p_codec ) < 0 )
- {
- if( p_context->channels > 2 )
- {
- p_context->channels = 2;
- //id->f_dst.i_channels = 2;
- if( avcodec_open( p_context, p_codec ) < 0 )
- {
- msg_Err( p_enc, "cannot open encoder" );
- return VLC_EGENERIC;
- }
- msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
- }
- else
- {
- msg_Err( p_enc, "cannot open encoder" );
- return VLC_EGENERIC;
- }
- }
-
- p_enc->i_extra_data = p_context->extradata_size;
- p_enc->p_extra_data = p_context->extradata;
- p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
-
- p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
- p_sys->p_buffer = malloc( p_sys->i_frame_size );
- p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
-
- msg_Warn( p_enc, "avcodec_setup_audio: %d %d %d %d",
- p_context->frame_size, p_context->bit_rate, p_context->channels,
- p_context->sample_rate );
-
- p_sys->i_samples_delay = 0;
- p_sys->i_pts = 0;
-
- msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
* EncodeAudio: the whole thing
****************************************************************************/
p_sys->i_pts = p_aout_buf->start_date -
(mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
- (mtime_t)p_enc->format.audio.i_rate;
+ (mtime_t)p_enc->fmt_in.audio.i_rate;
p_sys->i_samples_delay += i_samples;
}
/*****************************************************************************
- * CloseAudioEncoder: ffmpeg audio encoder destruction
+ * CloseEncoder: ffmpeg encoder destruction
*****************************************************************************/
-void E_(CloseAudioEncoder)( vlc_object_t *p_this )
+void E_(CloseEncoder)( vlc_object_t *p_this )
{
encoder_t *p_enc = (encoder_t *)p_this;
encoder_sys_t *p_sys = p_enc->p_sys;
avcodec_close( p_sys->p_context );
free( p_sys->p_context );
- free( p_sys->p_buffer );
- free( p_sys->p_buffer_out );
+
+ if( p_sys->p_buffer ) free( p_sys->p_buffer );
+ if( p_sys->p_buffer_out ) free( p_sys->p_buffer_out );
+
free( p_sys );
}
* ffmpeg.c: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.58 2003/10/29 20:53:41 gbazin Exp $
+ * $Id: ffmpeg.c,v 1.59 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
#include <string.h>
#include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/aout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#ifdef HAVE_SYS_TIMES_H
-# include <sys/times.h>
-#endif
-
/* ffmpeg header */
#ifdef HAVE_FFMPEG_AVCODEC_H
# include <ffmpeg/avcodec.h>
* Local prototypes
****************************************************************************/
static int OpenDecoder( vlc_object_t * );
-static int InitDecoder( decoder_t * );
-static int EndDecoder( decoder_t * );
-
-static int b_ffmpeginit = 0;
+static void CloseDecoder( vlc_object_t * );
/*****************************************************************************
* Module descriptor
/* decoder main module */
add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
set_capability( "decoder", 70 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
add_bool( "ffmpeg-dr", 1, NULL, DR_TEXT, DR_TEXT, VLC_TRUE );
set_callbacks( E_(OpenChroma), NULL );
set_description( _("ffmpeg chroma conversion") );
- /* video encoder submodule */
- add_submodule();
- set_description( _("ffmpeg video encoder") );
- set_capability( "video encoder", 100 );
- set_callbacks( E_(OpenVideoEncoder), E_(CloseVideoEncoder) );
-
- /* audio encoder submodule */
- add_submodule();
- set_description( _("ffmpeg audio encoder") );
- set_capability( "audio encoder", 10 );
- set_callbacks( E_(OpenAudioEncoder), E_(CloseAudioEncoder) );
-
+ /* encoder submodule */
+ add_submodule();
+ set_description( _("ffmpeg audio/video encoder") );
+ set_capability( "encoder", 100 );
+ set_callbacks( E_(OpenEncoder), E_(CloseEncoder) );
+
var_Create( p_module->p_libvlc, "avcodec", VLC_VAR_MUTEX );
vlc_module_end();
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*) p_this;
- int i_cat, i_codec_id;
+ int i_cat, i_codec_id, i_result;
char *psz_namecodec;
- if( !E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc, &i_cat, &i_codec_id,
+ AVCodecContext *p_context;
+ AVCodec *p_codec;
+
+ /* *** determine codec type *** */
+ if( !E_(GetFfmpegCodec)( p_dec->fmt_in.i_codec, &i_cat, &i_codec_id,
&psz_namecodec ) )
{
return VLC_EGENERIC;
/* Initialization must be done before avcodec_find_decoder() */
E_(InitLibavcodec)(p_this);
- if( !avcodec_find_decoder( i_codec_id ) )
- {
- msg_Dbg( p_dec, "codec not found (%s)", psz_namecodec );
- return VLC_EGENERIC;
- }
-
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = (i_cat == VIDEO_ES) ? E_(DecodeVideo) : E_(DecodeAudio);
- p_dec->pf_end = EndDecoder;
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- int i_cat, i_codec_id, i_result;
- char *psz_namecodec;
- AVCodecContext *p_context;
- AVCodec *p_codec;
-
- /* *** determine codec type *** */
- E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc,
- &i_cat, &i_codec_id, &psz_namecodec );
-
/* *** ask ffmpeg for a decoder *** */
if( !( p_codec = avcodec_find_decoder( i_codec_id ) ) )
{
- msg_Err( p_dec, "codec not found (%s)", psz_namecodec );
+ msg_Dbg( p_dec, "codec not found (%s)", psz_namecodec );
return VLC_EGENERIC;
}
/* *** get a p_context *** */
p_context = avcodec_alloc_context();
+ /* Set CPU capabilities */
+#ifdef HAVE_MMX
+ p_context->dsp_mask = 0;
+ if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
+ {
+ p_context->dsp_mask &= FF_MM_MMX;
+ }
+ if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
+ {
+ p_context->dsp_mask &= FF_MM_MMXEXT;
+ }
+ if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
+ {
+ p_context->dsp_mask &= FF_MM_3DNOW;
+ }
+ if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE )
+ {
+ p_context->dsp_mask &= FF_MM_SSE;
+ p_context->dsp_mask &= FF_MM_SSE2; /* FIXME */
+ }
+ /* Hack to make sure everything can be disabled **/
+ p_context->dsp_mask &= (FF_MM_FORCE >> 1);
+#endif
+
switch( i_cat )
{
case VIDEO_ES:
+ p_dec->pf_decode_video = E_(DecodeVideo);
i_result = E_( InitVideoDec )( p_dec, p_context, p_codec,
i_codec_id, psz_namecodec );
- p_dec->pf_decode = E_(DecodeVideo);
break;
case AUDIO_ES:
+ p_dec->pf_decode_audio = E_(DecodeAudio);
i_result = E_( InitAudioDec )( p_dec, p_context, p_codec,
i_codec_id, psz_namecodec );
- p_dec->pf_decode = E_(DecodeAudio);
break;
default:
i_result = VLC_EGENERIC;
return i_result;
}
-
+
/*****************************************************************************
- * EndDecoder: decoder destruction
+ * CloseDecoder: decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
if( !p_sys->p_context )
}
free( p_sys );
- return VLC_SUCCESS;
}
/*****************************************************************************
void E_(InitLibavcodec)( vlc_object_t *p_object )
{
+ static int b_ffmpeginit = 0;
vlc_value_t lockval;
var_Get( p_object->p_libvlc, "avcodec", &lockval );
vlc_mutex_lock( lockval.p_address );
- /* *** init ffmpeg library (libavcodec) *** */
+ /* *** init ffmpeg library (libavcodec) *** */
if( !b_ffmpeginit )
{
avcodec_init();
* ffmpeg.h: decoder using the ffmpeg library
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: ffmpeg.h,v 1.27 2003/10/27 01:04:38 gbazin Exp $
+ * $Id: ffmpeg.h,v 1.28 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
int E_( InitVideoDec )( decoder_t *, AVCodecContext *, AVCodec *,
int, char * );
void E_( EndVideoDec ) ( decoder_t * );
-int E_( DecodeVideo ) ( decoder_t *, block_t * );
+picture_t *E_( DecodeVideo ) ( decoder_t *, block_t ** );
/* Audio decoder module */
int E_( InitAudioDec )( decoder_t *, AVCodecContext *, AVCodec *,
int, char * );
void E_( EndAudioDec ) ( decoder_t * );
-int E_( DecodeAudio ) ( decoder_t *, block_t * );
+aout_buffer_t *E_( DecodeAudio ) ( decoder_t *, block_t ** );
/* Chroma conversion module */
int E_(OpenChroma)( vlc_object_t * );
/* Video encoder module */
-int E_(OpenVideoEncoder) ( vlc_object_t * );
-void E_(CloseVideoEncoder)( vlc_object_t * );
+int E_(OpenEncoder) ( vlc_object_t * );
+void E_(CloseEncoder)( vlc_object_t * );
/* Audio encoder module */
int E_(OpenAudioEncoder) ( vlc_object_t * );
* video.c: video decoder using the ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: video.c,v 1.43 2003/10/28 14:17:52 gbazin Exp $
+ * $Id: video.c,v 1.44 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
#include <string.h>
#include <vlc/vlc.h>
-#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#ifdef HAVE_SYS_TIMES_H
-# include <sys/times.h>
-#endif
-
/* ffmpeg header */
#ifdef HAVE_FFMPEG_AVCODEC_H
# include <ffmpeg/avcodec.h>
AVFrame *p_ff_pic;
BITMAPINFOHEADER *p_format;
- vout_thread_t *p_vout;
-
/* for frame skipping algo */
int b_hurry_up;
- int i_frame_error;
int i_frame_skip;
/* how many decoded frames are late */
vlc_bool_t b_has_b_frames;
- int i_buffer;
- char *p_buffer;
+ int i_buffer_orig, i_buffer;
+ char *p_buffer_orig, *p_buffer;
/* Postprocessing handle */
void *p_pp;
+ vlc_bool_t b_pp_init;
};
/*****************************************************************************
/*****************************************************************************
* Local Functions
*****************************************************************************/
-static inline uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
+static uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
{
- /* FIXME FIXME some of them are wrong */
switch( i_ff_chroma )
{
case PIX_FMT_YUV420P:
- case PIX_FMT_YUV422:
- return( VLC_FOURCC('I','4','2','0') );
- case PIX_FMT_RGB24:
- return( VLC_FOURCC('R','V','2','4') );
+ return VLC_FOURCC('I','4','2','0');
case PIX_FMT_YUV422P:
- return( VLC_FOURCC('I','4','2','2') );
+ return VLC_FOURCC('I','4','2','2');
case PIX_FMT_YUV444P:
- return( VLC_FOURCC('I','4','4','4') );
+ return VLC_FOURCC('I','4','4','4');
+
+ case PIX_FMT_YUV422:
+ return VLC_FOURCC('Y','U','Y','2');
+
+ case PIX_FMT_RGB555:
+ return VLC_FOURCC('R','V','1','5');
+ case PIX_FMT_RGB565:
+ return VLC_FOURCC('R','V','1','6');
+ case PIX_FMT_RGB24:
+ return VLC_FOURCC('R','V','2','4');
+ case PIX_FMT_RGBA32:
+ return VLC_FOURCC('R','V','3','2');
+ case PIX_FMT_GRAY8:
+ return VLC_FOURCC('G','R','E','Y');
+
case PIX_FMT_YUV410P:
case PIX_FMT_YUV411P:
case PIX_FMT_BGR24:
}
}
-/* Return a Vout */
-static vout_thread_t *ffmpeg_CreateVout( decoder_t *p_dec,
- AVCodecContext *p_context )
+/* Returns a new picture buffer */
+static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec,
+ AVCodecContext *p_context )
{
- vout_thread_t *p_vout;
- unsigned int i_width = p_context->width;
- unsigned int i_height = p_context->height;
- uint32_t i_chroma = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
- unsigned int i_aspect;
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ picture_t *p_pic;
- if( !i_width || !i_height )
+ p_dec->fmt_out.video.i_width = p_context->width;
+ p_dec->fmt_out.video.i_height = p_context->height;
+ p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
+
+ if( !p_context->width || !p_context->height )
{
- return( NULL ); /* Can't create a new vout without display size */
+ return NULL; /* invalid display size */
}
- if( !i_chroma )
+ if( !p_dec->fmt_out.i_codec )
{
/* we make conversion if possible*/
- i_chroma = VLC_FOURCC('I','4','2','0');
+ p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
}
#if LIBAVCODEC_BUILD >= 4687
- i_aspect = VOUT_ASPECT_FACTOR * ( av_q2d(p_context->sample_aspect_ratio) *
- p_context->width / p_context->height );
+ p_dec->fmt_out.video.i_aspect =
+ VOUT_ASPECT_FACTOR * ( av_q2d(p_context->sample_aspect_ratio) *
+ p_context->width / p_context->height );
#else
- i_aspect = VOUT_ASPECT_FACTOR * p_context->aspect_ratio;
+ p_dec->fmt_out.video.i_aspect =
+ VOUT_ASPECT_FACTOR * p_context->aspect_ratio;
#endif
- if( i_aspect == 0 )
+ if( p_dec->fmt_out.video.i_aspect == 0 )
{
- i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height;
+ p_dec->fmt_out.video.i_aspect =
+ VOUT_ASPECT_FACTOR * p_context->width / p_context->height;
}
- /* 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 = vout_Request( p_dec, p_dec->p_sys->p_vout,
- i_width, i_height, i_chroma, i_aspect );
+ p_pic = p_dec->pf_vout_buffer_new( p_dec );
#ifdef LIBAVCODEC_PP
- if( p_dec->p_sys->p_pp )
- E_(InitPostproc)( p_dec, p_dec->p_sys->p_pp, i_width, i_height,
- p_context->pix_fmt );
+ if( p_sys->p_pp && !p_sys->b_pp_init )
+ {
+ E_(InitPostproc)( p_dec, p_sys->p_pp, p_context->width,
+ p_context->height, p_context->pix_fmt );
+ p_sys->b_pp_init = VLC_TRUE;
+ }
#endif
- return p_vout;
+ return p_pic;
}
/*****************************************************************************
p_dec->p_sys->psz_namecodec = psz_namecodec;
p_sys->p_ff_pic = avcodec_alloc_frame();
- if( ( p_sys->p_format =
- (BITMAPINFOHEADER *)p_dec->p_fifo->p_bitmapinfoheader ) != NULL )
- {
- /* ***** Fill p_context with init values ***** */
- p_sys->p_context->width = p_sys->p_format->biWidth;
- p_sys->p_context->height = p_sys->p_format->biHeight;
- }
- else
- {
- msg_Warn( p_dec, "display informations missing" );
- p_sys->p_format = NULL;
- }
+ /* ***** Fill p_context with init values ***** */
+ p_sys->p_context->width = p_dec->fmt_in.video.i_width;
+ p_sys->p_context->height = p_dec->fmt_in.video.i_height;
/* ***** Get configuration of ffmpeg plugin ***** */
i_tmp = config_GetInt( p_dec, "ffmpeg-workaround-bugs" );
#ifdef LIBAVCODEC_PP
p_sys->p_pp = NULL;
+ p_dec->p_sys->b_pp_init = VLC_FALSE;
if( E_(OpenPostproc)( p_dec, &p_sys->p_pp ) == VLC_SUCCESS )
{
/* for now we cannot do postproc and dr */
p_sys->p_context->opaque = p_dec;
/* ***** init this codec with special data ***** */
- if( p_sys->p_format && p_sys->p_format->biSize > sizeof(BITMAPINFOHEADER) )
+ if( p_dec->fmt_in.i_extra )
{
int b_gotpicture;
- int i_size = p_sys->p_format->biSize - sizeof(BITMAPINFOHEADER);
+ int i_size = p_dec->fmt_in.i_extra;
if( p_sys->i_codec_id == CODEC_ID_MPEG4 )
{
uint8_t *p_vol = malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
-
- memcpy( p_vol, &p_sys->p_format[1], i_size );
+ memcpy( p_vol, p_dec->fmt_in.p_extra, i_size );
memset( &p_vol[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
memcpy( &p[0], "SVQ3", 4 );
memset( &p[4], 0, 8 );
- memcpy( &p[12], &p_sys->p_format[1], i_size );
+ memcpy( &p[12], p_dec->fmt_in.p_extra, i_size );
}
#endif
else
p_sys->p_context->extradata =
malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
memcpy( p_sys->p_context->extradata,
- &p_sys->p_format[1], i_size );
+ p_dec->fmt_in.p_extra, i_size );
memset( &((uint8_t*)p_sys->p_context->extradata)[i_size],
0, FF_INPUT_BUFFER_PADDING_SIZE );
}
}
/* ***** misc init ***** */
- p_sys->p_vout = NULL;
p_sys->input_pts = 0;
p_sys->i_pts = 0;
p_sys->b_has_b_frames = VLC_FALSE;
p_sys->i_late_frames = 0;
- p_sys->i_buffer = 1;
- p_sys->p_buffer = malloc( p_sys->i_buffer );
+ p_sys->i_buffer = 0;
+ p_sys->i_buffer_orig = 1;
+ p_sys->p_buffer_orig = p_sys->p_buffer = malloc( p_sys->i_buffer );
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = VIDEO_ES;
+ p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
return VLC_SUCCESS;
}
/*****************************************************************************
* DecodeVideo: Called to decode one or more frames
*****************************************************************************/
-int E_(DecodeVideo)( decoder_t *p_dec, block_t *p_block )
+picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_buffer, b_drawpicture;
- char *p_buffer;
+ int b_drawpicture;
+ block_t *p_block;
+
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
if( p_block->i_pts > 0 )
{
p_sys->input_pts = p_block->i_pts;
}
+#if 0
/* TODO implement it in a better way */
/* A good idea could be to decode all I pictures and see for the other */
if( p_sys->b_hurry_up && p_sys->i_late_frames > 4 )
p_sys->i_late_frames--; /* needed else it will never be decrease */
block_Release( p_block );
- return VLC_SUCCESS;
+ p_sys->i_buffer = 0;
+ return NULL;
}
}
else
p_sys->i_late_frames--;
return VLC_SUCCESS;
}
+#endif
if( !p_sys->p_context->width || !p_sys->p_context->height )
{
/* Don't forget that ffmpeg requires a little more bytes
* that the real frame size */
- i_buffer = p_block->i_buffer;
- if( i_buffer + FF_INPUT_BUFFER_PADDING_SIZE > p_sys->i_buffer )
+ if( p_block->i_buffer )
{
- free( p_sys->p_buffer );
- p_sys->i_buffer = i_buffer + FF_INPUT_BUFFER_PADDING_SIZE;
- p_sys->p_buffer = malloc( p_sys->i_buffer );
+ p_sys->i_buffer = p_block->i_buffer;
+ if( p_sys->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE >
+ p_sys->i_buffer_orig )
+ {
+ free( p_sys->p_buffer_orig );
+ p_sys->i_buffer_orig =
+ p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE;
+ p_sys->p_buffer_orig = malloc( p_sys->i_buffer_orig );
+ }
+ p_sys->p_buffer = p_sys->p_buffer_orig;
+ p_sys->i_buffer = p_block->i_buffer;
+ p_dec->p_vlc->pf_memcpy( p_sys->p_buffer, p_block->p_buffer,
+ p_block->i_buffer );
+ memset( p_sys->p_buffer + p_block->i_buffer, 0,
+ FF_INPUT_BUFFER_PADDING_SIZE );
+
+ p_block->i_buffer = 0;
}
- p_buffer = p_sys->p_buffer;
- p_dec->p_vlc->pf_memcpy( p_buffer, p_block->p_buffer, p_block->i_buffer );
- memset( p_buffer + i_buffer, 0, FF_INPUT_BUFFER_PADDING_SIZE );
- while( i_buffer )
+ while( p_sys->i_buffer )
{
int i_used, b_gotpicture;
picture_t *p_pic;
i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
&b_gotpicture,
- p_buffer, i_buffer );
+ p_sys->p_buffer, p_sys->i_buffer );
if( i_used < 0 )
{
- msg_Warn( p_dec, "cannot decode one frame (%d bytes)", i_buffer );
- p_sys->i_frame_error++;
+ msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
+ p_sys->i_buffer );
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
/* Consumed bytes */
- i_buffer -= i_used;
- p_buffer += i_used;
+ p_sys->i_buffer -= i_used;
+ p_sys->p_buffer += i_used;
/* Nothing to display */
if( !b_gotpicture ) continue;
if( !p_sys->b_direct_rendering )
{
- p_sys->p_vout = ffmpeg_CreateVout( p_dec, p_sys->p_context );
- if( !p_sys->p_vout )
- {
- msg_Err( p_dec, "cannot create vout" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
-
/* Get a new picture */
- while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+ p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
+ if( !p_pic )
{
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- {
- block_Release( p_block );
- return VLC_EGENERIC;
- }
- msleep( VOUT_OUTMEM_SLEEP );
+ block_Release( p_block );
+ return NULL;
}
/* Fill p_picture_t from AVVideoFrame and do chroma conversion
/* Send decoded frame to vout */
if( p_sys->i_pts )
{
- vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts );
- vout_DisplayPicture( p_sys->p_vout, p_pic );
+ p_pic->date = p_sys->i_pts;
/* interpolate the next PTS */
if( p_sys->p_context->frame_rate > 0 )
p_sys->p_context->frame_rate_base /
(2 * p_sys->p_context->frame_rate);
}
+ return p_pic;
+ }
+ else
+ {
+ p_dec->pf_vout_buffer_del( p_dec, p_pic );
}
}
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
E_(ClosePostproc)( p_dec, p_sys->p_pp );
#endif
- free( p_sys->p_buffer );
-
- /* We are about to die. Reattach video output to p_vlc. */
- vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
+ free( p_sys->p_buffer_orig );
}
/*****************************************************************************
return avcodec_default_get_buffer( p_context, p_ff_pic );
}
- /* Check and (re)create our vout if needed */
- p_sys->p_vout = ffmpeg_CreateVout( p_dec, p_sys->p_context );
- if( !p_sys->p_vout )
+ /* Get a new picture */
+ //p_sys->p_vout->render.b_allow_modify_pics = 0;
+ p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
+ if( !p_pic )
{
- msg_Err( p_dec, "cannot create vout" );
- p_dec->p_fifo->b_error = 1; /* abort */
p_sys->b_direct_rendering = 0;
return avcodec_default_get_buffer( p_context, p_ff_pic );
}
-
- p_sys->p_vout->render.b_allow_modify_pics = 0;
-
- /* Get a new picture */
- while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
- {
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- {
- p_sys->b_direct_rendering = 0;
- return avcodec_default_get_buffer( p_context, p_ff_pic );
- }
- msleep( VOUT_OUTMEM_SLEEP );
- }
p_sys->p_context->draw_horiz_band = NULL;
p_ff_pic->opaque = (void*)p_pic;
if( p_ff_pic->reference != 0 )
{
- vout_LinkPicture( p_sys->p_vout, p_pic );
+ //vout_LinkPicture( p_sys->p_vout, p_pic );
}
/* FIXME what is that, should give good value */
p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg
- return( 0 );
+ return 0;
}
-static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
- AVFrame *p_ff_pic )
+static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
+ AVFrame *p_ff_pic )
{
decoder_t *p_dec = (decoder_t *)p_context->opaque;
- decoder_sys_t *p_sys = p_dec->p_sys;
picture_t *p_pic;
if( p_ff_pic->type != FF_BUFFER_TYPE_USER )
if( p_ff_pic->reference != 0 )
{
- vout_UnlinkPicture( p_sys->p_vout, p_pic );
+ //vout_UnlinkPicture( p_sys->p_vout, p_pic );
}
}
* flac.c: flac decoder module making use of libflac
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: flacdec.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: flacdec.c,v 1.5 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
{
decoder_t *p_dec = (decoder_t*)p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('f','l','a','c') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('f','l','a','c') )
{
return VLC_EGENERIC;
}
* libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: libmpeg2.c,v 1.32 2003/11/04 17:46:17 gbazin Exp $
+ * $Id: libmpeg2.c,v 1.33 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Christophe Massiot <massiot@via.ecp.fr>
/*
* Output properties
*/
- vout_thread_t *p_vout;
vout_synchro_t *p_synchro;
+ int i_aspect;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int OpenDecoder( vlc_object_t * );
-static int InitDecoder( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static int OpenDecoder( vlc_object_t * );
+static void CloseDecoder( vlc_object_t * );
+
+static picture_t *DecodeBlock( decoder_t *, block_t ** );
static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
vlc_module_begin();
set_description( _("MPEG I/II video decoder (using libmpeg2)") );
set_capability( "decoder", 150 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_shortcut( "libmpeg2" );
vlc_module_end();
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','v') &&
- p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','1') &&
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','v') &&
+ p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','1') &&
/* Pinnacle hardware-mpeg1 */
- p_dec->p_fifo->i_fourcc != VLC_FOURCC('P','I','M','1') &&
+ p_dec->fmt_in.i_codec != VLC_FOURCC('P','I','M','1') &&
/* ATI Video */
- p_dec->p_fifo->i_fourcc != VLC_FOURCC('V','C','R','2') &&
- p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','2') )
+ p_dec->fmt_in.i_codec != VLC_FOURCC('V','C','R','2') &&
+ p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','2') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
}
/* Initialize the thread properties */
- memset( p_dec->p_sys, 0, sizeof(decoder_sys_t) );
- p_dec->p_sys->p_pes = NULL;
- p_dec->p_sys->p_vout = NULL;
- p_dec->p_sys->p_mpeg2dec = NULL;
- p_dec->p_sys->p_synchro = NULL;
- p_dec->p_sys->p_info = NULL;
- p_dec->p_sys->i_pts = mdate() + DEFAULT_PTS_DELAY;
- p_dec->p_sys->i_current_pts = 0;
- p_dec->p_sys->i_previous_pts = 0;
- p_dec->p_sys->p_picture_to_destroy = NULL;
- p_dec->p_sys->b_garbage_pic = 0;
- p_dec->p_sys->b_slice_i = 0;
- p_dec->p_sys->b_skip = 0;
+ memset( p_sys, 0, sizeof(decoder_sys_t) );
+ p_sys->p_pes = NULL;
+ p_sys->p_mpeg2dec = NULL;
+ p_sys->p_synchro = NULL;
+ p_sys->p_info = NULL;
+ p_sys->i_pts = mdate() + DEFAULT_PTS_DELAY;
+ p_sys->i_current_pts = 0;
+ p_sys->i_previous_pts = 0;
+ p_sys->p_picture_to_destroy = NULL;
+ p_sys->b_garbage_pic = 0;
+ p_sys->b_slice_i = 0;
+ p_sys->b_skip = 0;
/* Initialize decoder */
- p_dec->p_sys->p_mpeg2dec = mpeg2_init();
- if( p_dec->p_sys->p_mpeg2dec == NULL)
+ p_sys->p_mpeg2dec = mpeg2_init();
+ if( p_sys->p_mpeg2dec == NULL)
{
msg_Err( p_dec, "mpeg2_init() failed" );
- free( p_dec->p_sys );
+ free( p_sys );
return VLC_EGENERIC;
}
- p_dec->p_sys->p_info = mpeg2_info( p_dec->p_sys->p_mpeg2dec );
+ p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
+
+ p_dec->pf_decode_video = DecodeBlock;
return VLC_SUCCESS;
}
/*****************************************************************************
* RunDecoder: the libmpeg2 decoder
*****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
mpeg2_state_t state;
picture_t *p_pic;
- int i_aspect;
- vlc_bool_t b_need_more_data = VLC_FALSE;
+ block_t *p_block;
+
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
while( 1 )
{
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- {
- block_Release( p_block );
- return VLC_EGENERIC;
- }
-
state = mpeg2_parse( p_sys->p_mpeg2dec );
switch( state )
{
case STATE_BUFFER:
- if( !p_block->i_buffer || b_need_more_data )
+ if( !p_block->i_buffer )
{
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
if( p_block->b_discontinuity && p_sys->p_synchro
}
p_sys->p_picture_to_destroy = p_pic;
- memset( p_pic->p[0].p_pixels, 0,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height );
- memset( p_pic->p[1].p_pixels, 0x80,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height / 4 );
- memset( p_pic->p[2].p_pixels, 0x80,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height / 4 );
-
if ( p_sys->b_slice_i )
{
vout_SynchroNewPicture( p_sys->p_synchro,
mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
p_block->p_buffer + p_block->i_buffer );
- b_need_more_data = VLC_TRUE;
+ p_block->i_buffer = 0;
break;
case STATE_SEQUENCE:
uint8_t *buf[3];
buf[0] = buf[1] = buf[2] = NULL;
- /* Check whether the input gives a particular aspect ratio */
- if( p_dec->p_fifo->p_demux_data
- && ( *(int*)(p_dec->p_fifo->p_demux_data) & 0x7 ) )
+ /* Check whether the input gave a particular aspect ratio */
+ if( p_dec->fmt_in.video.i_aspect )
{
- i_aspect = *(int*)(p_dec->p_fifo->p_demux_data);
- switch( i_aspect )
+ p_sys->i_aspect = p_dec->fmt_in.video.i_aspect;
+ switch( p_sys->i_aspect )
{
case AR_3_4_PICTURE:
- i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
+ p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
break;
case AR_16_9_PICTURE:
- i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
+ p_sys->i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
break;
case AR_221_1_PICTURE:
- i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
+ p_sys->i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
break;
case AR_SQUARE_PICTURE:
default:
- i_aspect = VOUT_ASPECT_FACTOR *
+ p_sys->i_aspect = VOUT_ASPECT_FACTOR *
p_sys->p_info->sequence->width /
p_sys->p_info->sequence->height;
break;
else
{
/* Use the value provided in the MPEG sequence header */
- i_aspect = ((uint64_t)p_sys->p_info->sequence->display_width) *
+ p_sys->i_aspect =
+ ((uint64_t)p_sys->p_info->sequence->display_width) *
p_sys->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR /
p_sys->p_info->sequence->display_height /
p_sys->p_info->sequence->pixel_height;
}
- if ( p_dec->p_sys->p_vout != NULL )
- {
- int i_pic;
- /* Temporary hack to free the pictures in use by libmpeg2 */
- for ( i_pic = 0; i_pic < p_dec->p_sys->p_vout->render.i_pictures; i_pic++ )
- {
- if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_status ==
- RESERVED_PICTURE )
- vout_DestroyPicture( p_dec->p_sys->p_vout,
- p_dec->p_sys->p_vout->render.pp_picture[i_pic] );
- if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_refcount > 0 )
- vout_UnlinkPicture( p_dec->p_sys->p_vout,
- p_dec->p_sys->p_vout->render.pp_picture[i_pic] );
- }
- }
-
- p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
- p_sys->p_info->sequence->width,
- p_sys->p_info->sequence->height,
- VLC_FOURCC('Y','V','1','2'),
- i_aspect );
-
- if(p_sys->p_vout == NULL )
- {
- msg_Err( p_dec, "cannot create vout" );
- block_Release( p_block );
- return -1;
- }
-
msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps",
p_sys->p_info->sequence->width,
- p_sys->p_info->sequence->height, i_aspect,
+ p_sys->p_info->sequence->height, p_sys->i_aspect,
(uint32_t)((uint64_t)1001000000 * 27 /
- p_sys->p_info->sequence->frame_period / 1001),
+ p_sys->p_info->sequence->frame_period / 1001),
(uint32_t)((uint64_t)1001000000 * 27 /
- p_sys->p_info->sequence->frame_period % 1001) );
+ p_sys->p_info->sequence->frame_period % 1001) );
mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
/* Set the first 2 reference frames */
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
- if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break;
- memset( p_pic->p[0].p_pixels, 0,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height );
- memset( p_pic->p[1].p_pixels, 0x80,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height / 4 );
- memset( p_pic->p[2].p_pixels, 0x80,
- p_sys->p_info->sequence->width
- * p_sys->p_info->sequence->height / 4 );
+ if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
+ {
+ block_Release( p_block );
+ return NULL;
+ }
+
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
+
/* This picture will never go through display_picture. */
- vout_DatePicture( p_sys->p_vout, p_pic, 0 );
- vout_DisplayPicture( p_sys->p_vout, p_pic );
+ p_pic->date = 0;
+
/* For some reason, libmpeg2 will put this pic twice in
* discard_picture. This can be considered a bug in libmpeg2. */
- vout_LinkPicture( p_sys->p_vout, p_pic );
+ //vout_LinkPicture( p_sys->p_vout, p_pic );
- if ( p_sys->p_synchro )
+ if( p_sys->p_synchro )
{
vout_SynchroRelease( p_sys->p_synchro );
}
vout_SynchroNewPicture( p_sys->p_synchro,
p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
p_sys->p_info->current_picture->nb_fields,
- 0, 0,
- p_sys->i_current_rate );
+ 0, 0, p_sys->i_current_rate );
- if ( p_sys->b_skip )
+ if( p_sys->b_skip )
{
vout_SynchroTrash( p_sys->p_synchro );
}
uint8_t *buf[3];
buf[0] = buf[1] = buf[2] = NULL;
- if ( p_sys->b_after_sequence_header
- && ((p_sys->p_info->current_picture->flags
- & PIC_MASK_CODING_TYPE)
- == PIC_FLAG_CODING_TYPE_P) )
+ if ( p_sys->b_after_sequence_header &&
+ ((p_sys->p_info->current_picture->flags &
+ PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P) )
{
/* Intra-slice refresh. Simulate a blank I picture. */
msg_Dbg( p_dec, "intra-slice refresh stream" );
&& !vout_SynchroChoose( p_sys->p_synchro,
p_sys->p_info->current_picture->flags
& PIC_MASK_CODING_TYPE,
- p_sys->p_vout->render_time ) )
+ /*p_sys->p_vout->render_time*/ 0 /*FIXME*/ ) )
{
mpeg2_skip( p_sys->p_mpeg2dec, 1 );
p_sys->b_skip = 1;
mpeg2_skip( p_sys->p_mpeg2dec, 0 );
p_sys->b_skip = 0;
vout_SynchroDecode( p_sys->p_synchro );
- if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break;
+
+ if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
+ {
+ block_Release( p_block );
+ return NULL;
+ }
+
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
}
}
& PIC_MASK_CODING_TYPE,
p_sys->b_garbage_pic );
p_sys->b_garbage_pic = 0;
- vout_DisplayPicture( p_sys->p_vout, p_pic );
if ( p_sys->p_picture_to_destroy != p_pic )
{
- vout_DatePicture( p_sys->p_vout, p_pic,
- vout_SynchroDate( p_sys->p_synchro ) );
+ p_pic->date = vout_SynchroDate( p_sys->p_synchro );
}
else
{
p_sys->p_picture_to_destroy = NULL;
- vout_DatePicture( p_sys->p_vout, p_pic, 0 );
+ p_pic->date = 0;
}
+ return p_pic; /* FIXME */
}
if( p_sys->p_info->discard_fbuf &&
p_sys->p_info->discard_fbuf->id )
{
- p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id;
- vout_UnlinkPicture( p_sys->p_vout, p_pic );
+ //p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id;
+ //vout_UnlinkPicture( p_sys->p_vout, p_pic );
}
+
+ //return p_pic; /* FIXME */
+
break;
case STATE_INVALID:
msg_Warn( p_dec, "invalid picture encountered" );
if ( ( p_sys->p_info->current_picture == NULL ) ||
- ( ( p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE)
- != B_CODING_TYPE ) )
+ ( ( p_sys->p_info->current_picture->flags &
+ PIC_MASK_CODING_TYPE) != B_CODING_TYPE ) )
{
vout_SynchroReset( p_sys->p_synchro );
}
p_sys->p_info->sequence->width
* p_sys->p_info->sequence->height / 4 );
- if ( p_sys->b_slice_i )
+ if( p_sys->b_slice_i )
{
vout_SynchroNewPicture( p_sys->p_synchro,
I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate );
}
}
- block_Release( p_block );
- return VLC_EGENERIC;
+ /* Never reached */
+ return NULL;
}
/*****************************************************************************
- * EndDecoder: libmpeg2 decoder destruction
+ * CloseDecoder: libmpeg2 decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t * p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_sys )
- {
- int i_pic;
-
- if( p_sys->p_synchro )
- vout_SynchroRelease( p_sys->p_synchro );
-
- if( p_sys->p_vout )
- {
- /* Temporary hack to free the pictures in use by libmpeg2 */
- for( i_pic = 0; i_pic < p_sys->p_vout->render.i_pictures; i_pic++ )
- {
- if( p_sys->p_vout->render.pp_picture[i_pic]->i_status ==
- RESERVED_PICTURE )
- vout_DestroyPicture( p_sys->p_vout,
- p_sys->p_vout->render.pp_picture[i_pic] );
- if( p_sys->p_vout->render.pp_picture[i_pic]->i_refcount > 0 )
- vout_UnlinkPicture( p_sys->p_vout,
- p_sys->p_vout->render.pp_picture[i_pic] );
- }
-
- vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
- }
+ if( p_sys->p_synchro ) vout_SynchroRelease( p_sys->p_synchro );
- if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
+ if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
- free( p_sys );
- }
-
- return VLC_SUCCESS;
+ free( p_sys );
}
/*****************************************************************************
decoder_sys_t *p_sys = p_dec->p_sys;
picture_t *p_pic;
- vlc_bool_t b_progressive = p_sys->p_info->current_picture != NULL ?
- p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
- vlc_bool_t b_top_field_first = p_sys->p_info->current_picture != NULL ?
- p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
- unsigned int i_nb_fields = p_sys->p_info->current_picture != NULL ?
- p_sys->p_info->current_picture->nb_fields : 2;
+ p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
+ p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
+ p_dec->fmt_out.video.i_aspect = p_sys->i_aspect;
- /* Get a new picture */
- while( !( p_pic = vout_CreatePicture( p_sys->p_vout,
- b_progressive, b_top_field_first, i_nb_fields ) ) )
- {
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- break;
+ p_dec->fmt_out.i_codec =
+ ( p_sys->p_info->sequence->chroma_height <
+ p_sys->p_info->sequence->height ) ?
+ VLC_FOURCC('I','4','2','0') : VLC_FOURCC('I','4','2','2');
- msleep( VOUT_OUTMEM_SLEEP );
- }
+ /* Get a new picture */
+ p_pic = p_dec->pf_vout_buffer_new( p_dec );
if( p_pic == NULL ) return NULL;
- vout_LinkPicture( p_sys->p_vout, p_pic );
+ p_pic->b_progressive = p_sys->p_info->current_picture != NULL ?
+ p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
+ p_pic->b_top_field_first = p_sys->p_info->current_picture != NULL ?
+ p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
+ p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ?
+ p_sys->p_info->current_picture->nb_fields : 2;
+
+ //vout_LinkPicture( p_sys->p_vout, p_pic );
pp_buf[0] = p_pic->p[0].p_pixels;
pp_buf[1] = p_pic->p[1].p_pixels;
* lpcm.c: lpcm decoder module
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: lpcm.c,v 1.18 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
{
decoder_t *p_dec = (decoder_t*)p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('l','p','c','m')
- && p_dec->p_fifo->i_fourcc != VLC_FOURCC('l','p','c','b') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('l','p','c','m')
+ && p_dec->fmt_in.i_codec != VLC_FOURCC('l','p','c','b') )
{
return VLC_EGENERIC;
}
* mpeg_audio.c: parse MPEG audio sync info and packetize the stream
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
- * $Id: mpeg_audio.c,v 1.21 2003/10/23 21:28:11 gbazin Exp $
+ * $Id: mpeg_audio.c,v 1.22 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
*/
int i_state;
- block_t *p_chain;
block_bytestream_t bytestream;
- /*
- * Decoder output properties
- */
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
- audio_sample_format_t aout_format;
- aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
- sout_buffer_t * p_sout_buffer; /* current sout buffer */
-
/*
* Common properties
*/
- uint8_t *p_out_buffer; /* output buffer */
audio_date_t end_date;
unsigned int i_current_layer;
- mtime_t pts;
+ mtime_t i_pts;
int i_frame_size, i_free_frame_size;
unsigned int i_channels_conf, i_channels;
STATE_SYNC,
STATE_HEADER,
STATE_NEXT_SYNC,
- STATE_DATA
+ STATE_GET_DATA,
+ STATE_SEND_DATA
};
/* This isn't the place to put mad-specific stuff. However, it makes the
/****************************************************************************
* Local prototypes
****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int OpenDecoder ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+static void CloseDecoder ( vlc_object_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
-
-static int GetOutBuffer ( decoder_t *, uint8_t ** );
-static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
-static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
-static int SendOutBuffer( decoder_t * );
+static uint8_t *GetOutBuffer ( decoder_t *, void ** );
+static aout_buffer_t *GetAoutBuffer( decoder_t * );
+static block_t *GetSoutBuffer( decoder_t * );
static int SyncInfo( uint32_t i_header, unsigned int * pi_channels,
unsigned int * pi_channels_conf,
vlc_module_begin();
set_description( _("MPEG audio layer I/II/III parser") );
set_capability( "decoder", 100 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_submodule();
set_description( _("MPEG audio layer I/II/III packetizer") );
set_capability( "packetizer", 10 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, CloseDecoder );
vlc_module_end();
/*****************************************************************************
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','a') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- p_dec->p_sys->b_packetizer = VLC_FALSE;
+
+ /* Misc init */
+ p_sys->b_packetizer = VLC_FALSE;
+ p_sys->i_state = STATE_NOSYNC;
+ aout_DateSet( &p_sys->end_date, 0 );
+ p_sys->bytestream = block_BytestreamInit( p_dec );
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','g','a');
+
+ /* Set callback */
+ p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+
+ /* Start with the minimum size for a free bitrate frame */
+ p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
return VLC_SUCCESS;
}
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- p_dec->p_sys->i_state = STATE_NOSYNC;
-
- p_dec->p_sys->p_out_buffer = NULL;
- aout_DateSet( &p_dec->p_sys->end_date, 0 );
-
- p_dec->p_sys->p_aout = NULL;
- p_dec->p_sys->p_aout_input = NULL;
- p_dec->p_sys->p_aout_buffer = NULL;
- p_dec->p_sys->aout_format.i_format = VLC_FOURCC('m','p','g','a');
-
- p_dec->p_sys->p_sout_input = NULL;
- p_dec->p_sys->p_sout_buffer = NULL;
- p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
- p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC('m','p','g','a');
-
- /* Start with the minimum size for a free bitrate frame */
- p_dec->p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
-
- p_dec->p_sys->p_chain = NULL;
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function is called just after the thread is launched.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
uint8_t p_header[MAD_BUFFER_GUARD];
uint32_t i_header;
+ uint8_t *p_buf;
+ void *p_out_buffer;
+
+ if( !pp_block || !*pp_block ) return NULL;
- if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+ if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
{
/* We've just started the stream, wait for the first PTS. */
- block_Release( p_block );
- return VLC_SUCCESS;
+ block_Release( *pp_block );
+ return NULL;
}
- if( p_block->b_discontinuity )
+ if( (*pp_block)->b_discontinuity )
{
- p_sys->i_state = STATE_SYNC;
+ p_sys->i_state = STATE_NOSYNC;
}
- if( p_sys->p_chain )
- {
- block_ChainAppend( &p_sys->p_chain, p_block );
- }
- else
- {
- block_ChainAppend( &p_sys->p_chain, p_block );
- p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
- }
+ block_BytestreamPush( &p_sys->bytestream, *pp_block );
while( 1 )
{
}
if( p_sys->i_state != STATE_SYNC )
{
- if( block_PeekByte( &p_sys->bytestream, p_header )
- == VLC_SUCCESS && p_header[0] == 0xff )
- {
- /* Start of a sync word, need more data */
- return VLC_SUCCESS;
- }
-
- block_ChainRelease( p_sys->p_chain );
- p_sys->p_chain = NULL;
+ block_BytestreamFlush( &p_sys->bytestream );
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
case STATE_SYNC:
/* New frame, set the Presentation Time Stamp */
- p_sys->pts = p_sys->bytestream.p_block->i_pts;
- if( p_sys->pts != 0 &&
- p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+ if( p_sys->i_pts != 0 &&
+ p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->end_date, p_sys->pts );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
p_sys->i_state = STATE_HEADER;
- break;
case STATE_HEADER:
/* Get MPGA frame header (MPGA_HEADER_SIZE bytes) */
MPGA_HEADER_SIZE ) != VLC_SUCCESS )
{
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
/* Build frame header */
MAD_BUFFER_GUARD ) != VLC_SUCCESS )
{
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
if( p_header[0] == 0xff && (p_header[1] & 0xe0) == 0xe0 )
&i_next_max_frame_size,
&i_next_layer );
- if( i_next_frame_size == -1 )
- {
- msg_Dbg( p_dec, "emulated start code on next frame" );
- block_SkipByte( &p_sys->bytestream );
- p_sys->i_state = STATE_NOSYNC;
- break;
- }
-
/* Free bitrate only */
- if( p_sys->i_bit_rate == 0 )
+ if( p_sys->i_bit_rate == 0 && i_next_frame_size == -1 )
{
- if( i_next_bit_rate != 0 )
- {
- p_sys->i_frame_size++;
- break;
- }
-
if( (unsigned int)p_sys->i_frame_size >
p_sys->i_max_frame_size )
{
p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
break;
}
+
+ p_sys->i_frame_size++;
+ break;
+ }
+
+ if( i_next_frame_size == -1 )
+ {
+ msg_Dbg( p_dec, "emulated start code on next frame" );
+ block_SkipByte( &p_sys->bytestream );
+ p_sys->i_state = STATE_NOSYNC;
+ break;
}
/* Check info is in sync with previous one */
p_sys->i_state = STATE_NOSYNC;
break;
}
+
+ /* Free bitrate only */
+ if( p_sys->i_bit_rate == 0 )
+ {
+ if( i_next_bit_rate != 0 )
+ {
+ p_sys->i_frame_size++;
+ break;
+ }
+ }
+
}
else
{
/* Free bitrate only */
if( p_sys->i_bit_rate == 0 )
{
+ if( (unsigned int)p_sys->i_frame_size >
+ p_sys->i_max_frame_size )
+ {
+ msg_Dbg( p_dec, "frame too big %d > %d "
+ "(emulated startcode ?)", p_sys->i_frame_size,
+ p_sys->i_max_frame_size );
+ block_SkipByte( &p_sys->bytestream );
+ p_sys->i_state = STATE_NOSYNC;
+ p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
+ break;
+ }
+
p_sys->i_frame_size++;
break;
}
break;
}
- if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS )
+ p_sys->i_state = STATE_SEND_DATA;
+ break;
+
+ case STATE_GET_DATA:
+ /* Make sure we have enough data.
+ * (Not useful if we went through NEXT_SYNC) */
+ if( block_WaitBytes( &p_sys->bytestream,
+ p_sys->i_frame_size ) != VLC_SUCCESS )
{
- return VLC_EGENERIC;
+ /* Need more data */
+ return NULL;
}
+ p_sys->i_state = STATE_SEND_DATA;
- /* Free bitrate only */
- if( p_sys->i_bit_rate == 0 )
+ case STATE_SEND_DATA:
+ if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
{
- p_sys->i_free_frame_size = p_sys->i_frame_size;
+ //p_dec->b_error = VLC_TRUE;
+ return NULL;
}
- p_sys->i_state = STATE_DATA;
-
- case STATE_DATA:
- /* Copy the whole frame into the buffer */
- if( block_GetBytes( &p_sys->bytestream, p_sys->p_out_buffer,
- p_sys->i_frame_size ) != VLC_SUCCESS )
+ /* Free bitrate only */
+ if( p_sys->i_bit_rate == 0 )
{
- /* Need more data */
- return VLC_SUCCESS;
+ p_sys->i_free_frame_size = p_sys->i_frame_size;
}
- p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
+ /* Copy the whole frame into the buffer. When we reach this point
+ * we already know we have enough data available. */
+ block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
/* Get beginning of next frame for libmad */
if( !p_sys->b_packetizer )
{
- memcpy( p_sys->p_out_buffer + p_sys->i_frame_size,
+ memcpy( p_buf + p_sys->i_frame_size,
p_header, MAD_BUFFER_GUARD );
}
- SendOutBuffer( p_dec );
p_sys->i_state = STATE_NOSYNC;
/* Make sure we don't reuse the same pts twice */
- if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
- p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
+ if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
+
+ /* So p_block doesn't get re-added several times */
+ *pp_block = block_BytestreamPop( &p_sys->bytestream );
+
+ return p_out_buffer;
}
}
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
* GetOutBuffer:
*****************************************************************************/
-static int GetOutBuffer( decoder_t *p_dec, uint8_t **pp_out_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_ret;
+ uint8_t *p_buf;
+
+ if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
+ {
+ msg_Info( p_dec, "MPGA channels:%d samplerate:%d bitrate:%d",
+ p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
+
+ aout_DateInit( &p_sys->end_date, p_sys->i_rate );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
+ }
+
+ p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
+ p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+ p_dec->fmt_out.audio.i_bitrate = p_sys->i_bit_rate;
+ p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
+ p_dec->fmt_out.audio.i_bytes_per_frame =
+ p_sys->i_max_frame_size + MAD_BUFFER_GUARD;
+
+ p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
if( p_sys->b_packetizer )
{
- i_ret = GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
- *pp_out_buffer =
- p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
+ block_t *p_sout_buffer = GetSoutBuffer( p_dec );
+ p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
+ *pp_out_buffer = p_sout_buffer;
}
else
{
- i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
- *pp_out_buffer =
- p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer : NULL;
+ aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
+ p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
+ *pp_out_buffer = p_aout_buffer;
}
- return i_ret;
+ return p_buf;
}
/*****************************************************************************
* GetAoutBuffer:
*****************************************************************************/
-static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
+static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ aout_buffer_t *p_buf;
- if( p_sys->p_aout_input != NULL &&
- ( p_sys->aout_format.i_rate != p_sys->i_rate
- || p_sys->aout_format.i_original_channels != p_sys->i_channels_conf
- || p_sys->aout_format.i_bytes_per_frame !=
- p_sys->i_max_frame_size + MAD_BUFFER_GUARD
- || p_sys->aout_format.i_frame_length != p_sys->i_frame_length
- || p_sys->i_current_layer != p_sys->i_layer ) )
- {
- /* Parameters changed - this should not happen. */
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- p_sys->p_aout_input = NULL;
- }
+ p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length );
+ if( p_buf == NULL ) return NULL;
- /* Creating the audio input if not created yet. */
- if( p_sys->p_aout_input == NULL )
- {
- p_sys->i_current_layer = p_sys->i_layer;
- if( p_sys->i_layer == 3 )
- {
- p_sys->aout_format.i_format = VLC_FOURCC('m','p','g','3');
- }
- else
- {
- p_sys->aout_format.i_format = VLC_FOURCC('m','p','g','a');
- }
+ p_buf->start_date = aout_DateGet( &p_sys->end_date );
+ p_buf->end_date =
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
- p_sys->aout_format.i_rate = p_sys->i_rate;
- p_sys->aout_format.i_original_channels = p_sys->i_channels_conf;
- p_sys->aout_format.i_physical_channels
- = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
- p_sys->aout_format.i_bytes_per_frame = p_sys->i_max_frame_size
- + MAD_BUFFER_GUARD;
- p_sys->aout_format.i_frame_length = p_sys->i_frame_length;
- aout_DateInit( &p_sys->end_date, p_sys->i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
- p_sys->p_aout_input = aout_DecNew( p_dec,
- &p_sys->p_aout,
- &p_sys->aout_format );
- if( p_sys->p_aout_input == NULL )
- {
- *pp_buffer = NULL;
- return VLC_EGENERIC;
- }
- }
-
- *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
- p_sys->i_frame_length );
- if( *pp_buffer == NULL )
- {
- return VLC_EGENERIC;
- }
+ /* Hack for libmad filter */
+ p_buf->i_nb_bytes = p_sys->i_frame_size + MAD_BUFFER_GUARD;
- (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
- (*pp_buffer)->end_date =
- aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
-
- return VLC_SUCCESS;
+ return p_buf;
}
/*****************************************************************************
* GetSoutBuffer:
*****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static block_t *GetSoutBuffer( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
- if( p_sys->p_sout_input != NULL &&
- ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
- || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
- {
- /* Parameters changed - this should not happen. */
- }
+ p_block = block_New( p_dec, p_sys->i_frame_size );
+ if( p_block == NULL ) return NULL;
- /* Creating the sout input if not created yet. */
- if( p_sys->p_sout_input == NULL )
- {
- p_sys->sout_format.i_sample_rate = p_sys->i_rate;
- p_sys->sout_format.i_channels = p_sys->i_channels;
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = p_sys->i_bit_rate;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
+ p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
- aout_DateInit( &p_sys->end_date, p_sys->i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
-
- p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
- if( p_sys->p_sout_input == NULL )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- *pp_buffer = NULL;
- return VLC_EGENERIC;
- }
- msg_Info( p_dec, "MPGA channels:%d samplerate:%d bitrate:%d",
- p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
- }
-
- *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
- p_sys->i_frame_size );
- if( *pp_buffer == NULL )
- {
- return VLC_EGENERIC;
- }
+ p_block->i_length =
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) -
+ p_block->i_pts;
- (*pp_buffer)->i_pts =
- (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
-
- (*pp_buffer)->i_length =
- aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length )
- - (*pp_buffer)->i_pts;
-
- return VLC_SUCCESS;
+ return p_block;
}
/*****************************************************************************
- * SendOutBuffer:
+ * CloseDecoder: clean up the decoder
*****************************************************************************/
-static int SendOutBuffer( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_sys->b_packetizer )
- {
- sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
- p_sys->p_sout_buffer = NULL;
- }
- else
- {
- /* We have all we need, send the buffer to the aout core. */
- p_sys->p_aout_buffer->i_nb_bytes =
- p_sys->i_frame_size + MAD_BUFFER_GUARD;
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
- p_sys->p_aout_buffer );
- p_sys->p_aout_buffer = NULL;
- }
-
- p_sys->p_out_buffer = NULL;
+ block_BytestreamRelease( &p_sys->bytestream );
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * EndDecoder: clean up the decoder
- *****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
-{
- if( p_dec->p_sys->p_aout_input != NULL )
- {
- if( p_dec->p_sys->p_aout_buffer )
- {
- aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
- p_dec->p_sys->p_aout_input,
- p_dec->p_sys->p_aout_buffer );
- }
-
- aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
- }
-
- if( p_dec->p_sys->p_sout_input != NULL )
- {
- if( p_dec->p_sys->p_sout_buffer )
- {
- sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
- p_dec->p_sys->p_sout_buffer );
- }
-
- sout_InputDelete( p_dec->p_sys->p_sout_input );
- }
-
- if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
-
- free( p_dec->p_sys );
-
- return VLC_SUCCESS;
+ free( p_sys );
}
/*****************************************************************************
* rawvideo.c: Pseudo video decoder/packetizer for raw video data
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: rawvideo.c,v 1.7 2003/10/24 21:27:06 gbazin Exp $
+ * $Id: rawvideo.c,v 1.8 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
#include <string.h> /* strdup() */
#include <vlc/vlc.h>
-#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#include <vlc/sout.h>
#include "codecs.h"
*/
int i_raw_size;
- /*
- * Output properties
- */
- vout_thread_t *p_vout;
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
-
/*
* Common properties
*/
/****************************************************************************
* Local prototypes
****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int OpenDecoder ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+static void CloseDecoder ( vlc_object_t * );
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
-static int DecodeFrame ( decoder_t *, block_t * );
-static int SendFrame ( decoder_t *, block_t * );
+static picture_t *DecodeFrame( decoder_t *, block_t * );
+static block_t *SendFrame ( decoder_t *, block_t * );
/*****************************************************************************
* Module descriptor
vlc_module_begin();
set_description( _("Pseudo Raw Video decoder") );
set_capability( "decoder", 50 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_submodule();
set_description( _("Pseudo Raw Video packetizer") );
set_capability( "packetizer", 100 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, CloseDecoder );
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_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- switch( p_dec->p_fifo->i_fourcc )
+ switch( p_dec->fmt_in.i_codec )
{
/* Planar YUV */
case VLC_FOURCC('I','4','4','4'):
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
+ /* Misc init */
p_dec->p_sys->b_packetizer = VLC_FALSE;
+ p_sys->i_pts = 0;
+
+ if( p_dec->fmt_in.video.i_width <= 0 ||
+ p_dec->fmt_in.video.i_height <= 0 )
+ {
+ msg_Err( p_dec, "invalid display size %dx%d",
+ p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
+ return VLC_EGENERIC;
+ }
+
+ /* Find out p_vdec->i_raw_size */
+ vout_InitFormat( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec,
+ p_dec->fmt_in.video.i_width,
+ p_dec->fmt_in.video.i_height,
+ p_dec->fmt_in.video.i_aspect );
+ p_sys->i_raw_size = p_dec->fmt_out.video.i_bits_per_pixel *
+ p_dec->fmt_out.video.i_width * p_dec->fmt_out.video.i_height / 8;
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = VIDEO_ES;
+ p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
+ //if( !p_dec->fmt_in.video.i_aspect )
+ {
+ p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+ p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height;
+ }
+
+ /* Set callbacks */
+ p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
return VLC_SUCCESS;
}
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- video_frame_format_t format;
-
- p_sys->i_pts = 0;
-
- p_sys->p_sout_input = NULL;
- p_sys->sout_format.i_cat = VIDEO_ES;
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = 0;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
-
-#define bih ((BITMAPINFOHEADER*)p_dec->p_fifo->p_bitmapinfoheader)
- if( bih == NULL )
- {
- msg_Err( p_dec, "info missing, fatal" );
- return VLC_EGENERIC;
- }
- if( bih->biWidth <= 0 || bih->biHeight <= 0 )
- {
- msg_Err( p_dec, "invalid display size %dx%d",
- bih->biWidth, bih->biHeight );
- return VLC_EGENERIC;
- }
-
- if( p_sys->b_packetizer )
- {
- /* add an input for the stream ouput */
- p_sys->sout_format.i_width = bih->biWidth;
- p_sys->sout_format.i_height = bih->biHeight;
- p_sys->sout_format.i_fourcc = p_dec->p_fifo->i_fourcc;
-
- p_sys->p_sout_input =
- sout_InputNew( p_dec, &p_sys->sout_format );
-
- if( !p_sys->p_sout_input )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- return VLC_EGENERIC;
- }
- }
- else
- {
- /* Initialize video output */
- p_sys->p_vout = vout_Request( p_dec, NULL,
- bih->biWidth, bih->biHeight,
- p_dec->p_fifo->i_fourcc,
- VOUT_ASPECT_FACTOR * bih->biWidth /
- bih->biHeight );
- if( p_sys->p_vout == NULL )
- {
- msg_Err( p_dec, "failed to create vout" );
- return VLC_EGENERIC;
- }
- }
-
- /* Find out p_vdec->i_raw_size */
- vout_InitFormat( &format, p_dec->p_fifo->i_fourcc,
- bih->biWidth, bih->biHeight,
- bih->biWidth * VOUT_ASPECT_FACTOR / bih->biHeight );
- p_sys->i_raw_size = format.i_bits_per_pixel *
- format.i_width * format.i_height / 8;
-#undef bih
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
- * This function must be fed with ogg packets.
+ * This function must be fed with complete frames.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_ret;
+ block_t *p_block;
+ void *p_buf;
+
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
-#if 0
- if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+ if( !p_sys->i_pts && !p_block->i_pts )
{
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
-#endif
/* Date management */
if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
p_block->i_buffer, p_sys->i_raw_size );
block_Release( p_block );
- return VLC_EGENERIC;
+ return NULL;
}
if( p_sys->b_packetizer )
{
- i_ret = SendFrame( p_dec, p_block );
+ p_buf = SendFrame( p_dec, p_block );
}
else
{
- i_ret = DecodeFrame( p_dec, p_block );
+ p_buf = DecodeFrame( p_dec, p_block );
}
/* Date management: 1 frame per packet */
p_sys->i_pts += ( I64C(1000000) * 1.0 / 25 /*FIXME*/ );
+ *pp_block = NULL;
- block_Release( p_block );
- return i_ret;
+ return p_buf;
}
/*****************************************************************************
/*****************************************************************************
* DecodeFrame: decodes a video frame.
*****************************************************************************/
-static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
+static picture_t *DecodeFrame( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
picture_t *p_pic;
/* Get a new picture */
- while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+ p_pic = p_dec->pf_vout_buffer_new( p_dec );
+ if( !p_pic )
{
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- {
- return VLC_EGENERIC;
- }
- msleep( VOUT_OUTMEM_SLEEP );
+ block_Release( p_block );
+ return NULL;
}
- if( !p_pic ) return VLC_EGENERIC;
FillPicture( p_dec, p_block, p_pic );
- vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts );
- vout_DisplayPicture( p_sys->p_vout, p_pic );
+ p_pic->date = p_sys->i_pts;
- return VLC_SUCCESS;
+ block_Release( p_block );
+ return p_pic;
}
/*****************************************************************************
* SendFrame: send a video frame to the stream output.
*****************************************************************************/
-static int SendFrame( decoder_t *p_dec, block_t *p_block )
+static block_t *SendFrame( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- sout_buffer_t *p_sout_buffer =
- sout_BufferNew( p_sys->p_sout_input->p_sout, p_block->i_buffer );
-
- if( !p_sout_buffer ) return VLC_EGENERIC;
+ p_block->i_dts = p_block->i_pts = p_sys->i_pts;
- p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
- p_block->p_buffer, p_block->i_buffer );
-
- p_sout_buffer->i_dts = p_sout_buffer->i_pts = p_sys->i_pts;
-
- sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
-
- return VLC_SUCCESS;
+ return p_block;
}
/*****************************************************************************
- * EndDecoder: decoder destruction
+ * CloseDecoder: decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
- decoder_sys_t *p_sys = p_dec->p_sys;
-
- if( !p_sys->b_packetizer )
- {
- vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
- }
-
- if( p_sys->p_sout_input != NULL )
- {
- sout_InputDelete( p_sys->p_sout_input );
- }
-
- free( p_sys );
-
- return VLC_SUCCESS;
+ decoder_t *p_dec = (decoder_t*)p_this;
+ free( p_dec->p_sys );
}
* speex.c: speex decoder/packetizer module making use of libspeex.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: speex.c,v 1.2 2003/10/22 18:24:08 gbazin Exp $
+ * $Id: speex.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
#include <string.h> /* memcpy(), memset() */
#include <vlc/vlc.h>
-#include <vlc/aout.h>
#include <vlc/decoder.h>
-#include <vlc/input.h>
-#include <vlc/sout.h>
-#include <input_ext-dec.h>
-
#include <vlc/input.h>
#include <ogg/ogg.h>
* Input properties
*/
int i_headers;
+ int i_frame_in_packet;
/*
* Speex properties
SpeexStereoState stereo;
void *p_state;
- /*
- * Output properties
- */
- aout_instance_t *p_aout;
- aout_input_t *p_aout_input;
- audio_sample_format_t aout_format;
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
-
/*
* Common properties
*/
- audio_date_t end_date;
+ audio_date_t end_date;
};
/****************************************************************************
* Local prototypes
****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int OpenDecoder ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+static void CloseDecoder ( vlc_object_t * );
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
+static int ProcessHeader ( decoder_t *, ogg_packet * );
+static void *ProcessPacket( decoder_t *, ogg_packet *, block_t ** );
-static int ProcessHeader ( decoder_t *, ogg_packet * );
-static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
-static int DecodePacket ( decoder_t *, ogg_packet * );
-static int SendPacket ( decoder_t *, ogg_packet * );
+static aout_buffer_t *DecodePacket( decoder_t *, ogg_packet * );
+static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
static void ParseSpeexComments( decoder_t *, ogg_packet * );
vlc_module_begin();
set_description( _("Speex audio decoder") );
set_capability( "decoder", 100 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_submodule();
set_description( _("Speex audio packetizer") );
set_capability( "packetizer", 100 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, CloseDecoder );
vlc_module_end();
/*****************************************************************************
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','x',' ') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','p','x',' ') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
}
p_dec->p_sys->b_packetizer = VLC_FALSE;
+ aout_DateSet( &p_sys->end_date, 0 );
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
+
+ /* Set callbacks */
+ p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+
+ p_sys->i_headers = 0;
+ p_sys->p_state = NULL;
+ p_sys->p_header = NULL;
+ p_sys->i_frame_in_packet = 0;
+
return VLC_SUCCESS;
}
int i_ret = OpenDecoder( p_this );
- if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+ if( i_ret == VLC_SUCCESS )
+ {
+ p_dec->p_sys->b_packetizer = VLC_TRUE;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('s','p','x',' ');
+ }
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
-
- aout_DateSet( &p_sys->end_date, 0 );
-
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = NULL;
- p_sys->aout_format.i_format = VLC_FOURCC('s','p','x',' ');
-
- p_sys->p_sout_input = NULL;
- p_sys->sout_format.i_cat = AUDIO_ES;
- p_sys->sout_format.i_fourcc = VLC_FOURCC( 's', 'p', 'x', ' ' );
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = 0;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
-
- p_sys->i_headers = 0;
- p_sys->p_state = NULL;
- p_sys->p_header = NULL;
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
ogg_packet oggpacket;
- int i_ret;
- /* Block to Ogg packet */
- oggpacket.packet = p_block->p_buffer;
- oggpacket.bytes = p_block->i_buffer;
+ if( !pp_block ) return NULL;
+
+ if( *pp_block )
+ {
+ /* Block to Ogg packet */
+ oggpacket.packet = (*pp_block)->p_buffer;
+ oggpacket.bytes = (*pp_block)->i_buffer;
+ }
+ else
+ {
+ if( p_sys->b_packetizer ) return NULL;
+
+ /* Block to Ogg packet */
+ oggpacket.packet = NULL;
+ oggpacket.bytes = 0;
+ }
+
oggpacket.granulepos = -1;
oggpacket.b_o_s = 0;
oggpacket.e_o_s = 0;
if( ProcessHeader( p_dec, &oggpacket ) != VLC_SUCCESS )
{
msg_Err( p_dec, "Initial Speex header is corrupted" );
- block_Release( p_block );
- return VLC_EGENERIC;
+ block_Release( *pp_block );
+ return NULL;
}
p_sys->i_headers++;
- if( p_sys->b_packetizer )
- {
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
if( p_sys->i_headers == 1 )
ParseSpeexComments( p_dec, &oggpacket );
p_sys->i_headers++;
- if( p_sys->b_packetizer )
- {
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
- }
-
- if( p_sys->i_headers < p_sys->p_header->extra_headers + 2 )
- {
- /* Skip them for now */
- p_sys->i_headers++;
-
- if( p_sys->b_packetizer )
- {
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
/*****************************************************************************
( p_header->nb_channels == 1 ) ? " (mono" : " (stereo",
p_header->vbr ? ", VBR)" : ")" );
- aout_DateInit( &p_sys->end_date, p_header->rate );
-
- if( p_sys->b_packetizer )
- {
- /* add an input for the stream ouput */
- p_sys->sout_format.i_sample_rate = p_header->rate;
- p_sys->sout_format.i_channels = p_header->nb_channels;
- p_sys->sout_format.i_block_align = 1;
- p_sys->sout_format.i_bitrate = 0;
-
- p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
- if( !p_sys->p_sout_input )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- return VLC_EGENERIC;
- }
-
- /* We're done */
- return VLC_SUCCESS;
- }
-
/* Take care of speex decoder init */
speex_bits_init( &p_sys->bits );
p_sys->p_state = p_state = speex_decoder_init( p_mode );
speex_decoder_ctl( p_state, SPEEX_SET_HANDLER, &callback );
}
- p_sys->aout_format.i_format = AOUT_FMT_S16_NE;
- p_sys->aout_format.i_physical_channels =
- p_sys->aout_format.i_original_channels =
+ /* Setup the format */
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
pi_channels_maps[p_header->nb_channels];
- p_sys->aout_format.i_rate = p_header->rate;
+ p_dec->fmt_out.audio.i_channels = p_header->nb_channels;
+ p_dec->fmt_out.audio.i_rate = p_header->rate;
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
- &p_sys->aout_format );
- if( p_sys->p_aout_input == NULL )
- {
- msg_Err( p_dec, "failed to create aout fifo" );
- return VLC_EGENERIC;
- }
+ aout_DateInit( &p_sys->end_date, p_header->rate );
return VLC_SUCCESS;
}
/*****************************************************************************
* ProcessPacket: processes a Speex packet.
*****************************************************************************/
-static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- mtime_t i_pts )
+static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block = *pp_block;
/* Date management */
- if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
+ if( p_block && p_block->i_pts > 0 &&
+ p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->end_date, i_pts );
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
}
if( !aout_DateGet( &p_sys->end_date ) )
{
/* We've just started the stream, wait for the first PTS. */
- return VLC_SUCCESS;
+ if( p_block ) block_Release( p_block );
+ return NULL;
}
+ *pp_block = NULL; /* To avoid being fed the same packet again */
+
if( p_sys->b_packetizer )
{
- return SendPacket( p_dec, p_oggpacket );
+ return SendPacket( p_dec, p_oggpacket, p_block );
}
else
{
- return DecodePacket( p_dec, p_oggpacket );
+ aout_buffer_t *p_aout_buffer;
+
+ if( p_sys->i_headers >= p_sys->p_header->extra_headers + 2 )
+ p_aout_buffer = DecodePacket( p_dec, p_oggpacket );
+ else
+ p_aout_buffer = NULL; /* Skip headers */
+
+ if( p_block )
+ {
+ block_Release( p_block );
+ }
+ return p_aout_buffer;
}
}
/*****************************************************************************
* DecodePacket: decodes a Speex packet.
*****************************************************************************/
-static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int j;
- /* Copy Ogg packet to Speex bitstream */
- speex_bits_read_from( &p_sys->bits, p_oggpacket->packet,
- p_oggpacket->bytes );
+ if( p_oggpacket->bytes )
+ {
+ /* Copy Ogg packet to Speex bitstream */
+ speex_bits_read_from( &p_sys->bits, p_oggpacket->packet,
+ p_oggpacket->bytes );
+ p_sys->i_frame_in_packet = 0;
+ }
- /* Decode each frame of the packet */
- for( j = 0; j != p_sys->p_header->frames_per_packet; j++ )
+ /* Decode one frame at a time */
+ if( p_sys->i_frame_in_packet < p_sys->p_header->frames_per_packet )
{
aout_buffer_t *p_aout_buffer;
int i_ret;
- p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
- p_sys->p_header->frame_size );
+ p_aout_buffer =
+ p_dec->pf_aout_buffer_new( p_dec, p_sys->p_header->frame_size );
if( !p_aout_buffer )
{
- msg_Err( p_dec, "cannot get aout buffer" );
- return VLC_SUCCESS;
+ return NULL;
}
i_ret = speex_decode( p_sys->p_state, &p_sys->bits,
(int16_t *)p_aout_buffer->p_buffer );
- if( i_ret == -1 ) break; /* End of stream */
+ if( i_ret == -1 ) return NULL; /* End of stream */
if( i_ret== -2 )
{
msg_Warn( p_dec, "Decoding error: corrupted stream?" );
- break;
+ return NULL;
}
if( speex_bits_remaining( &p_sys->bits ) < 0 )
{
msg_Warn( p_dec, "Decoding overflow: corrupted stream?" );
- break;
}
if( p_sys->p_header->nb_channels == 2 )
p_aout_buffer->end_date =
aout_DateIncrement( &p_sys->end_date, p_sys->p_header->frame_size);
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
- }
+ p_sys->i_frame_in_packet++;
- return VLC_SUCCESS;
+ return p_aout_buffer;
+ }
+ else
+ {
+ return NULL;
+ }
}
/*****************************************************************************
* SendPacket: send an ogg packet to the stream output.
*****************************************************************************/
-static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- sout_buffer_t *p_sout_buffer =
- sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
-
- if( !p_sout_buffer ) return VLC_EGENERIC;
-
- p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
- p_oggpacket->packet,
- p_oggpacket->bytes );
-
- p_sout_buffer->i_bitrate = 0;
-
/* Date management */
- p_sout_buffer->i_dts = p_sout_buffer->i_pts =
- aout_DateGet( &p_sys->end_date );
+ p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
if( p_sys->i_headers >= p_sys->p_header->extra_headers + 2 )
- p_sout_buffer->i_length =
+ p_block->i_length =
aout_DateIncrement( &p_sys->end_date,
p_sys->p_header->frame_size ) -
- p_sout_buffer->i_pts;
+ p_block->i_pts;
else
- p_sout_buffer->i_length = 0;
+ p_block->i_length = 0;
- sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
-
- return VLC_SUCCESS;
+ return p_block;
}
/*****************************************************************************
}
/*****************************************************************************
- * EndDecoder: speex decoder destruction
+ * CloseDecoder: speex decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t * p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t * p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_sys->p_aout_input != NULL )
- {
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
-
- if( p_sys->p_sout_input != NULL )
- {
- sout_InputDelete( p_sys->p_sout_input );
- }
-
if( p_sys->p_state )
{
speex_decoder_destroy( p_sys->p_state );
if( p_sys->p_header ) free( p_sys->p_header );
free( p_sys );
-
- return VLC_SUCCESS;
}
* spudec.c : SPU decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: spudec.c,v 1.26 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: spudec.c,v 1.27 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
{
decoder_t *p_dec = (decoder_t*)p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ')
- && p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','p','u',' ')
+ && p_dec->fmt_in.i_codec != VLC_FOURCC('s','p','u','b') )
{
return VLC_EGENERIC;
}
* subsdec.c : text subtitles decoder
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: subsdec.c,v 1.6 2003/11/15 15:40:19 hartman Exp $
+ * $Id: subsdec.c,v 1.7 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Samuel Hocevar <sam@zoy.org>
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
+static void CloseDecoder ( vlc_object_t * );
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void DecodeBlock ( decoder_t *, block_t ** );
static void ParseText ( decoder_t *, block_t *, vout_thread_t * );
vlc_module_begin();
set_description( _("text subtitles decoder") );
set_capability( "decoder", 50 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_category_hint( N_("Subtitles"), NULL, VLC_FALSE );
add_integer( "subsdec-align", 0, NULL, ALIGN_TEXT, ALIGN_LONGTEXT,
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
+ vlc_value_t val;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') &&
- p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','s','a',' ') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','u','b','t') &&
+ p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
+ p_dec->pf_decode_sub = DecodeBlock;
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- subtitle_data_t *p_demux_data = (subtitle_data_t *)p_dec->p_fifo->p_demux_data;
- vlc_value_t val;
-
var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_dec, "subsdec-align", &val );
p_sys->i_align = val.i_int;
if( val.psz_string ) free( val.psz_string );
#else
+
msg_Dbg( p_dec, "No iconv support available" );
#endif
}
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with complete subtitles units.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
vout_thread_t *p_vout;
if( !p_vout )
{
msg_Warn( p_dec, "couldn't find a video output, trashing subtitle" );
- return VLC_SUCCESS;
}
- ParseText( p_dec, p_block, p_vout );
+ ParseText( p_dec, *pp_block, p_vout );
vlc_object_release( p_vout );
-
- return VLC_SUCCESS;
}
/*****************************************************************************
- * EndDecoder: clean up the decoder
+ * CloseDecoder: clean up the decoder
*****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
vout_thread_t *p_vout;
#endif
free( p_sys );
-
- return VLC_SUCCESS;
}
/*****************************************************************************
* tarkin.c: tarkin decoder module making use of libtarkin.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: tarkin.c,v 1.6 2003/10/25 00:49:13 sam Exp $
+ * $Id: tarkin.c,v 1.7 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
{
decoder_t *p_dec = (decoder_t*)p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','a','r','k') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','a','r','k') )
{
return VLC_EGENERIC;
}
* theora.c: theora decoder module making use of libtheora.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: theora.c,v 1.13 2003/10/25 00:49:13 sam Exp $
+ * $Id: theora.c,v 1.14 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
#include <string.h> /* memcpy(), memset() */
#include <vlc/vlc.h>
-#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
-#include <vlc/sout.h>
-#include <input_ext-dec.h>
#include <ogg/ogg.h>
theora_comment tc; /* theora comment header */
theora_state td; /* theora bitstream user comments */
- /*
- * Output properties
- */
- vout_thread_t *p_vout;
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
-
/*
* Common properties
*/
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int OpenDecoder ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+static void CloseDecoder ( vlc_object_t * );
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
+static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
-static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
-static int DecodePacket ( decoder_t *, ogg_packet * );
-static int SendPacket ( decoder_t *, ogg_packet * );
+static picture_t *DecodePacket( decoder_t *, ogg_packet * );
static void ParseTheoraComments( decoder_t * );
static void theora_CopyPicture( decoder_t *, picture_t *, yuv_buffer * );
vlc_module_begin();
set_description( _("Theora video decoder") );
set_capability( "decoder", 100 );
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_shortcut( "theora" );
add_submodule();
set_description( _("Theora video packetizer") );
set_capability( "packetizer", 100 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, CloseDecoder );
add_shortcut( "theora" );
add_submodule();
set_description( _("Theora video encoder") );
- set_capability( "video encoder", 100 );
+ set_capability( "encoder", 100 );
set_callbacks( OpenEncoder, CloseEncoder );
add_shortcut( "theora" );
vlc_module_end();
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','h','e','o') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','h','e','o') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
}
p_dec->p_sys->b_packetizer = VLC_FALSE;
+ p_sys->i_pts = 0;
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = VIDEO_ES;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
+
+ /* Set callbacks */
+ p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+
+ /* Init supporting Theora structures needed in header parsing */
+ theora_comment_init( &p_sys->tc );
+ theora_info_init( &p_sys->ti );
+
+ p_sys->i_headers = 0;
+
return VLC_SUCCESS;
}
int i_ret = OpenDecoder( p_this );
- if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+ if( i_ret == VLC_SUCCESS )
+ {
+ p_dec->p_sys->b_packetizer = VLC_TRUE;
+ p_dec->fmt_out.i_codec = VLC_FOURCC( 't', 'h', 'e', 'o' );
+ }
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
-
- p_sys->i_pts = 0;
-
- p_sys->p_sout_input = NULL;
- p_sys->sout_format.i_cat = VIDEO_ES;
- p_sys->sout_format.i_fourcc = VLC_FOURCC( 't', 'h', 'e', 'o' );
- p_sys->sout_format.i_width = 0;
- p_sys->sout_format.i_height = 0;
- p_sys->sout_format.i_bitrate = 0;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
-
- /* Init supporting Theora structures needed in header parsing */
- theora_comment_init( &p_sys->tc );
- theora_info_init( &p_sys->ti );
-
- p_sys->i_headers = 0;
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
ogg_packet oggpacket;
- int i_ret;
+
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
/* Block to Ogg packet */
oggpacket.packet = p_block->p_buffer;
oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
{
- msg_Err( p_dec->p_fifo, "This bitstream does not contain Theora "
+ msg_Err( p_dec, "This bitstream does not contain Theora "
"video data" );
block_Release( p_block );
- return VLC_EGENERIC;
+ return NULL;
}
p_sys->i_headers++;
+ /* Set output properties */
+ p_dec->fmt_out.video.i_width = p_sys->ti.width;
+ p_dec->fmt_out.video.i_height = p_sys->ti.height;
- if( p_sys->b_packetizer )
- {
- /* add a input for the stream ouput */
- p_sys->sout_format.i_width = p_sys->ti.width;
- p_sys->sout_format.i_height = p_sys->ti.height;
-
- p_sys->p_sout_input =
- sout_InputNew( p_dec, &p_sys->sout_format );
-
- if( !p_sys->p_sout_input )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
- }
+ if( p_sys->ti.aspect_denominator )
+ p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+ p_sys->ti.aspect_numerator / p_sys->ti.aspect_denominator;
else
- {
- /* Initialize video output */
- int i_chroma, i_aspect;
-
- if( p_sys->ti.aspect_denominator )
- i_aspect = VOUT_ASPECT_FACTOR * p_sys->ti.aspect_numerator /
- p_sys->ti.aspect_denominator;
- else
- i_aspect = VOUT_ASPECT_FACTOR *
- p_sys->ti.frame_width / p_sys->ti.frame_height;
-
- i_chroma = VLC_FOURCC('Y','V','1','2');
-
- p_sys->p_vout =
- vout_Request( p_dec, NULL,
- p_sys->ti.frame_width, p_sys->ti.frame_height,
- i_chroma, i_aspect );
- if( p_sys->p_vout == NULL )
- {
- msg_Err( p_dec, "failed to create video output" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
- }
+ p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+ p_sys->ti.frame_width / p_sys->ti.frame_height;
msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
"is %dx%d with offset (%d,%d)",
p_sys->ti.frame_width, p_sys->ti.frame_height,
p_sys->ti.offset_x, p_sys->ti.offset_y );
- if( p_sys->b_packetizer )
- {
- i_ret = SendPacket( p_dec, &oggpacket );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
if( p_sys->i_headers == 1 )
if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
{
msg_Err( p_dec, "2nd Theora header is corrupted" );
- return VLC_EGENERIC;
+ return NULL;
}
p_sys->i_headers++;
ParseTheoraComments( p_dec );
- if( p_sys->b_packetizer )
- {
- i_ret = SendPacket( p_dec, &oggpacket );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
if( p_sys->i_headers == 2 )
if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
{
msg_Err( p_dec, "3rd Theora header is corrupted" );
- return VLC_EGENERIC;
+ return NULL;
}
p_sys->i_headers++;
theora_decode_init( &p_sys->td, &p_sys->ti );
}
- if( p_sys->b_packetizer )
- {
- i_ret = SendPacket( p_dec, &oggpacket );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
/*****************************************************************************
- * ProcessPacket: processes a Vorbis packet.
+ * ProcessPacket: processes a theora packet.
*****************************************************************************/
-static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- mtime_t i_pts )
+static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block = *pp_block;
+ void *p_buf;
/* Date management */
- if( i_pts > 0 && i_pts != p_sys->i_pts )
+ if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
{
- p_sys->i_pts = i_pts;
+ p_sys->i_pts = p_block->i_pts;
}
if( p_sys->b_packetizer )
{
- return SendPacket( p_dec, p_oggpacket );
+ /* Date management */
+ p_block->i_dts = p_block->i_pts = p_sys->i_pts;
+
+ if( p_sys->i_headers >= 3 )
+ p_block->i_length = p_sys->i_pts - p_block->i_pts;
+ else
+ p_block->i_length = 0;
+
+ p_buf = p_block;
}
else
{
- return DecodePacket( p_dec, p_oggpacket );
- }
-}
-
-/*****************************************************************************
- * DecodePacket: decodes a Theora packet.
- *****************************************************************************/
-static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
-{
- picture_t *p_pic;
- yuv_buffer yuv;
-
- decoder_sys_t *p_sys = p_dec->p_sys;
-
- theora_decode_packetin( &p_sys->td, p_oggpacket );
-
- /* Decode */
- theora_decode_YUVout( &p_sys->td, &yuv );
+ if( p_sys->i_headers >= 3 )
+ p_buf = DecodePacket( p_dec, p_oggpacket );
+ else
+ p_buf = NULL;
- /* Get a new picture */
- while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
- {
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
+ if( p_block )
{
- return VLC_EGENERIC;
+ block_Release( p_block );
+ *pp_block = NULL;
}
- msleep( VOUT_OUTMEM_SLEEP );
}
- if( !p_pic ) return VLC_EGENERIC;
-
- theora_CopyPicture( p_dec, p_pic, &yuv );
-
- vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts );
- vout_DisplayPicture( p_sys->p_vout, p_pic );
/* Date management */
p_sys->i_pts += ( I64C(1000000) * p_sys->ti.fps_denominator /
p_sys->ti.fps_numerator ); /* 1 frame per packet */
- return VLC_SUCCESS;
+ return p_buf;
}
/*****************************************************************************
- * SendPacket: send an ogg packet to the stream output.
+ * DecodePacket: decodes a Theora packet.
*****************************************************************************/
-static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ picture_t *p_pic;
+ yuv_buffer yuv;
- sout_buffer_t *p_sout_buffer =
- sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
-
- if( !p_sout_buffer ) return VLC_EGENERIC;
+ theora_decode_packetin( &p_sys->td, p_oggpacket );
- p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
- p_oggpacket->packet,
- p_oggpacket->bytes );
+ /* Decode */
+ theora_decode_YUVout( &p_sys->td, &yuv );
- /* Date management */
- p_sout_buffer->i_dts = p_sout_buffer->i_pts = p_sys->i_pts;
- p_sys->i_pts += ( I64C(1000000) * p_sys->ti.fps_denominator /
- p_sys->ti.fps_numerator ); /* 1 frame per packet */
+ /* Get a new picture */
+ p_pic = p_dec->pf_vout_buffer_new( p_dec );
+ if( !p_pic ) return NULL;
- if( p_sys->i_headers >= 3 )
- p_sout_buffer->i_length = p_sys->i_pts - p_sout_buffer->i_pts;
- else
- p_sout_buffer->i_length = 0;
+ theora_CopyPicture( p_dec, p_pic, &yuv );
- sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
+ p_pic->date = p_sys->i_pts;
- return VLC_SUCCESS;
+ return p_pic;
}
/*****************************************************************************
}
/*****************************************************************************
- * EndDecoder: theora decoder destruction
+ * CloseDecoder: theora decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t *p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( !p_sys->b_packetizer )
- vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 );
-
- if( p_sys->p_sout_input != NULL )
- {
- sout_InputDelete( p_sys->p_sout_input );
- }
-
theora_info_clear( &p_sys->ti );
theora_comment_clear( &p_sys->tc );
free( p_sys );
-
- return VLC_SUCCESS;
}
/*****************************************************************************
/*
* Input properties
*/
- int i_headers;
+ vlc_bool_t b_headers;
/*
* Theora properties
theora_comment tc; /* theora comment header */
theora_state td; /* theora bitstream user comments */
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
-
/*
* Common properties
*/
encoder_t *p_enc = (encoder_t *)p_this;
encoder_sys_t *p_sys = p_enc->p_sys;
- if( p_enc->i_fourcc != VLC_FOURCC('t','h','e','o') )
+ if( p_enc->fmt_out.i_codec != VLC_FOURCC('t','h','e','o') )
{
return VLC_EGENERIC;
}
p_enc->pf_header = Headers;
p_enc->pf_encode_video = Encode;
- p_enc->format.video.i_chroma = VLC_FOURCC('I','4','2','0');
+ p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
#define frame_x_offset 0
#define frame_y_offset 0
theora_info_init( &p_sys->ti );
- p_sys->ti.width = p_enc->format.video.i_width;
- p_sys->ti.height = p_enc->format.video.i_height;
- p_sys->ti.frame_width = p_enc->format.video.i_width;
- p_sys->ti.frame_height = p_enc->format.video.i_height;
+ p_sys->ti.width = p_enc->fmt_in.video.i_width;
+ p_sys->ti.height = p_enc->fmt_in.video.i_height;
+ p_sys->ti.frame_width = p_enc->fmt_in.video.i_width;
+ p_sys->ti.frame_height = p_enc->fmt_in.video.i_height;
p_sys->ti.offset_x = frame_x_offset;
p_sys->ti.offset_y = frame_y_offset;
p_sys->ti.fps_numerator = video_hzn;
p_sys->ti.aspect_numerator = video_an;
p_sys->ti.aspect_denominator = video_ad;
p_sys->ti.colorspace = not_specified;
- p_sys->ti.target_bitrate = p_enc->i_bitrate;
+ p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
p_sys->ti.quality = video_q;
p_sys->ti.dropframes_p = 0;
p_sys->ti.keyframe_auto_p = 1;
p_sys->ti.keyframe_frequency = 64;
p_sys->ti.keyframe_frequency_force = 64;
- p_sys->ti.keyframe_data_target_bitrate = p_enc->i_bitrate * 1.5;
+ p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
p_sys->ti.keyframe_auto_threshold = 80;
p_sys->ti.keyframe_mindistance = 8;
p_sys->ti.noise_sensitivity = 1;
theora_info_clear( &p_sys->ti );
theora_comment_init( &p_sys->tc );
- p_sys->i_headers = 0;
+ p_sys->b_headers = VLC_FALSE;
return VLC_SUCCESS;
}
static block_t *Headers( encoder_t *p_enc )
{
encoder_sys_t *p_sys = p_enc->p_sys;
- ogg_packet oggpacket;
- block_t *p_block;
+ block_t *p_chain = NULL;
/* Create theora headers */
- switch( p_sys->i_headers )
+ if( !p_sys->b_headers )
{
- case 0:
- theora_encode_header( &p_sys->td, &oggpacket );
- break;
- case 1:
- theora_encode_comment( &p_sys->tc, &oggpacket );
- break;
- case 2:
- theora_encode_tables( &p_sys->td, &oggpacket );
- break;
- default:
- break;
- }
+ ogg_packet oggpackets[3];
+ int i;
- p_sys->i_headers++;
- if( p_sys->i_headers > 3 ) return NULL;
+ theora_encode_header( &p_sys->td, &oggpackets[0] );
+ theora_encode_comment( &p_sys->tc, &oggpackets[1] );
+ theora_encode_tables( &p_sys->td, &oggpackets[2] );
- /* Ogg packet to block */
- p_block = block_New( p_enc, oggpacket.bytes );
- p_block->p_buffer = oggpacket.packet;
- p_block->i_buffer = oggpacket.bytes;
- p_block->i_dts = oggpacket.granulepos;
+ /* Ogg packet to block */
+ for( i = 0; i < 3; i++ )
+ {
+ block_t *p_block = block_New( p_enc, oggpackets[i].bytes );
+ memcpy( p_block->p_buffer, oggpackets[i].packet,
+ oggpackets[i].bytes );
+ p_block->i_dts = p_block->i_pts = p_block->i_length = 0;
+ block_ChainAppend( &p_chain, p_block );
+ }
- return p_block;
+ p_sys->b_headers = VLC_TRUE;
+ }
+
+ return p_chain;
}
/****************************************************************************
yuv.u = p_pict->p[1].p_pixels;
yuv.v = p_pict->p[2].p_pixels;
- theora_encode_YUVin( &p_sys->td, &yuv );
+ if( theora_encode_YUVin( &p_sys->td, &yuv ) < 0 )
+ {
+ msg_Warn( p_enc, "failed encoding a frame" );
+ return NULL;
+ }
theora_encode_packetout( &p_sys->td, 0, &oggpacket );
* vorbis.c: vorbis decoder/encoder/packetizer module making use of libvorbis.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: vorbis.c,v 1.21 2003/10/27 17:50:54 gbazin Exp $
+ * $Id: vorbis.c,v 1.22 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
#include <string.h> /* memcpy(), memset() */
#include <vlc/vlc.h>
-#include <vlc/aout.h>
#include <vlc/decoder.h>
-#include <vlc/input.h>
-#include <vlc/sout.h>
-#include <input_ext-dec.h>
-
#include <vlc/input.h>
#include <ogg/ogg.h>
* decoder */
vorbis_block vb; /* local working space for packet->PCM decode */
- /*
- * Output properties
- */
- aout_instance_t *p_aout;
- aout_input_t *p_aout_input;
- audio_sample_format_t aout_format;
-
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
-
/*
* Common properties
*/
- audio_date_t end_date;
- int i_last_block_size;
+ audio_date_t end_date;
+ int i_last_block_size;
};
/****************************************************************************
* Local prototypes
****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-static int OpenPacketizer( vlc_object_t * );
+static int OpenDecoder ( vlc_object_t * );
+static int OpenPacketizer( vlc_object_t * );
+static void CloseDecoder ( vlc_object_t * );
+static void *DecodeBlock ( decoder_t *, block_t ** );
-static int InitDecoder ( decoder_t * );
-static int RunDecoder ( decoder_t *, block_t * );
-static int EndDecoder ( decoder_t * );
+static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
-static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
-static int DecodePacket ( decoder_t *, ogg_packet * );
-static int SendPacket ( decoder_t *, ogg_packet * );
+static aout_buffer_t *DecodePacket ( decoder_t *, ogg_packet * );
+static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
static void ParseVorbisComments( decoder_t * );
#else
set_capability( "decoder", 100 );
#endif
- set_callbacks( OpenDecoder, NULL );
+ set_callbacks( OpenDecoder, CloseDecoder );
add_submodule();
set_description( _("Vorbis audio packetizer") );
set_capability( "packetizer", 100 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, CloseDecoder );
#ifndef MODULE_NAME_IS_tremor
add_submodule();
set_description( _("Vorbis audio encoder") );
- set_capability( "audio encoder", 100 );
+ set_capability( "encoder", 100 );
set_callbacks( OpenEncoder, CloseEncoder );
#endif
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('v','o','r','b') )
{
return VLC_EGENERIC;
}
- p_dec->pf_init = InitDecoder;
- p_dec->pf_decode = RunDecoder;
- p_dec->pf_end = EndDecoder;
-
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- p_dec->p_sys->b_packetizer = VLC_FALSE;
+
+ /* Misc init */
+ aout_DateSet( &p_sys->end_date, 0 );
+ p_sys->b_packetizer = VLC_FALSE;
+ p_sys->i_headers = 0;
+
+ /* Take care of vorbis init */
+ vorbis_info_init( &p_sys->vi );
+ vorbis_comment_init( &p_sys->vc );
+
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+#ifdef MODULE_NAME_IS_tremor
+ p_dec->fmt_out.i_codec = VLC_FOURCC('f','i','3','2');
+#else
+ p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
+#endif
+
+ /* Set callbacks */
+ p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
return VLC_SUCCESS;
}
int i_ret = OpenDecoder( p_this );
- if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
+ if( i_ret == VLC_SUCCESS )
+ {
+ p_dec->p_sys->b_packetizer = VLC_TRUE;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('v','o','r','b');
+ }
return i_ret;
}
-/*****************************************************************************
- * InitDecoder: Initalize the decoder
- *****************************************************************************/
-static int InitDecoder( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
-
- aout_DateSet( &p_sys->end_date, 0 );
-
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = NULL;
- p_sys->aout_format.i_format = VLC_FOURCC('v','o','r','b');
-
- p_sys->p_sout_input = NULL;
- p_sys->sout_format.i_cat = AUDIO_ES;
- p_sys->sout_format.i_fourcc = VLC_FOURCC( 'v', 'o', 'r', 'b' );
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = 0;
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
-
- /* Take care of vorbis init */
- vorbis_info_init( &p_sys->vi );
- vorbis_comment_init( &p_sys->vc );
-
- p_sys->i_headers = 0;
-
- return VLC_SUCCESS;
-}
-
/****************************************************************************
- * RunDecoder: the whole thing
+ * DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static int RunDecoder( decoder_t *p_dec, block_t *p_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
ogg_packet oggpacket;
- int i_ret;
- /* Block to Ogg packet */
- oggpacket.packet = p_block->p_buffer;
- oggpacket.bytes = p_block->i_buffer;
+ if( !pp_block ) return NULL;
+
+ if( *pp_block )
+ {
+ /* Block to Ogg packet */
+ oggpacket.packet = (*pp_block)->p_buffer;
+ oggpacket.bytes = (*pp_block)->i_buffer;
+ }
+ else
+ {
+ if( p_sys->b_packetizer ) return NULL;
+
+ /* Block to Ogg packet */
+ oggpacket.packet = NULL;
+ oggpacket.bytes = 0;
+ }
+
oggpacket.granulepos = -1;
oggpacket.b_o_s = 0;
oggpacket.e_o_s = 0;
if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc,
&oggpacket ) < 0 )
{
- msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis "
+ msg_Err( p_dec, "This bitstream does not contain Vorbis "
"audio data");
- block_Release( p_block );
- return VLC_EGENERIC;
+ block_Release( *pp_block );
+ return NULL;
}
p_sys->i_headers++;
-
- if( p_sys->b_packetizer )
- {
- /* add a input for the stream ouput */
- p_sys->sout_format.i_sample_rate = p_sys->vi.rate;
- p_sys->sout_format.i_channels = p_sys->vi.channels;
- p_sys->sout_format.i_block_align = 1;
- p_sys->sout_format.i_bitrate = p_sys->vi.bitrate_nominal;
-
- p_sys->p_sout_input =
- sout_InputNew( p_dec, &p_sys->sout_format );
-
- if( !p_sys->p_sout_input )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
- }
- else
- {
-#ifdef MODULE_NAME_IS_tremor
- p_sys->aout_format.i_format = VLC_FOURCC('f','i','3','2');
-#else
- p_sys->aout_format.i_format = VLC_FOURCC('f','l','3','2');
-#endif
- p_sys->aout_format.i_physical_channels =
- p_sys->aout_format.i_original_channels =
- pi_channels_maps[p_sys->vi.channels];
- p_sys->aout_format.i_rate = p_sys->vi.rate;
-
- p_sys->p_aout = NULL;
- p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
- &p_sys->aout_format );
-
- if( p_sys->p_aout_input == NULL )
- {
- msg_Err( p_dec, "failed to create aout fifo" );
- block_Release( p_block );
- return VLC_EGENERIC;
- }
- }
+ /* Setup the format */
+ p_dec->fmt_out.audio.i_rate = p_sys->vi.rate;
+ p_dec->fmt_out.audio.i_channels = p_sys->vi.channels;
+ p_dec->fmt_out.audio.i_bitrate = p_sys->vi.bitrate_nominal;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_dec->fmt_out.audio.i_original_channels =
+ pi_channels_maps[p_sys->vi.channels];
aout_DateInit( &p_sys->end_date, p_sys->vi.rate );
p_sys->vi.channels, p_sys->vi.rate,
p_sys->vi.bitrate_nominal );
- if( p_sys->b_packetizer )
- {
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
if( p_sys->i_headers == 1 )
< 0 )
{
msg_Err( p_dec, "2nd Vorbis header is corrupted" );
- return VLC_EGENERIC;
+ block_Release( *pp_block );
+ return NULL;
}
p_sys->i_headers++;
ParseVorbisComments( p_dec );
- if( p_sys->b_packetizer )
- {
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
if( p_sys->i_headers == 2 )
< 0 )
{
msg_Err( p_dec, "3rd Vorbis header is corrupted" );
- return VLC_EGENERIC;
+ block_Release( *pp_block );
+ return NULL;
}
p_sys->i_headers++;
vorbis_block_init( &p_sys->vd, &p_sys->vb );
}
- if( p_sys->b_packetizer )
- {
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
- }
- else
- {
- block_Release( p_block );
- return VLC_SUCCESS;
- }
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
- i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
- block_Release( p_block );
- return i_ret;
+ return ProcessPacket( p_dec, &oggpacket, pp_block );
}
/*****************************************************************************
* ProcessPacket: processes a Vorbis packet.
*****************************************************************************/
-static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- mtime_t i_pts )
+static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block = *pp_block;
/* Date management */
- if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
+ if( p_block && p_block->i_pts > 0 &&
+ p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->end_date, i_pts );
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
}
if( !aout_DateGet( &p_sys->end_date ) )
{
/* We've just started the stream, wait for the first PTS. */
- return VLC_SUCCESS;
+ if( p_block ) block_Release( p_block );
+ return NULL;
}
+ *pp_block = NULL; /* To avoid being fed the same packet again */
+
if( p_sys->b_packetizer )
{
- return SendPacket( p_dec, p_oggpacket );
+ return SendPacket( p_dec, p_oggpacket, p_block );
}
else
{
- return DecodePacket( p_dec, p_oggpacket );
+ aout_buffer_t *p_aout_buffer;
+
+ if( p_sys->i_headers >= 3 )
+ p_aout_buffer = DecodePacket( p_dec, p_oggpacket );
+ else
+ p_aout_buffer = NULL;
+
+ if( p_block )
+ {
+ block_Release( p_block );
+ }
+ return p_aout_buffer;
}
}
/*****************************************************************************
* DecodePacket: decodes a Vorbis packet.
*****************************************************************************/
-static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
decoder_sys_t *p_sys = p_dec->p_sys;
int i_samples;
float **pp_pcm;
#endif
- if( vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
+ if( p_oggpacket->bytes &&
+ vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb );
/* **pp_pcm is a multichannel float vector. In stereo, for
* the size of each channel. Convert the float values
* (-1.<=range<=1.) to whatever PCM format and write it out */
- while( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
+ if( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
{
aout_buffer_t *p_aout_buffer;
- p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
- i_samples );
- if( !p_aout_buffer )
- {
- msg_Err( p_dec, "cannot get aout buffer" );
- return VLC_SUCCESS;
- }
+
+ p_aout_buffer =
+ p_dec->pf_aout_buffer_new( p_dec, i_samples );
+
+ if( p_aout_buffer == NULL ) return NULL;
/* Interleave the samples */
#ifdef MODULE_NAME_IS_tremor
p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
i_samples );
-
- aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
+ return p_aout_buffer;
+ }
+ else
+ {
+ return NULL;
}
-
}
/*****************************************************************************
- * SendPacket: send an ogg packet to the stream output.
+ * SendPacket: send an ogg dated packet to the stream output.
*****************************************************************************/
-static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
+static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- int i_block_size, i_samples;
-
- sout_buffer_t *p_sout_buffer =
- sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
-
- if( !p_sout_buffer ) return VLC_EGENERIC;
+ int i_block_size, i_samples;
i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket );
if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
p_sys->i_last_block_size = i_block_size;
- p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
- p_oggpacket->packet,
- p_oggpacket->bytes );
-
- p_sout_buffer->i_bitrate = p_sys->vi.bitrate_nominal;
-
/* Date management */
- p_sout_buffer->i_dts = p_sout_buffer->i_pts =
- aout_DateGet( &p_sys->end_date );
+ p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
if( p_sys->i_headers >= 3 )
- p_sout_buffer->i_length =
- aout_DateIncrement( &p_sys->end_date, i_samples ) -
- p_sout_buffer->i_pts;
+ p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) -
+ p_block->i_pts;
else
- p_sout_buffer->i_length = 0;
-
- sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
+ p_block->i_length = 0;
- return VLC_SUCCESS;
+ return p_block;
}
/*****************************************************************************
}
/*****************************************************************************
- * EndDecoder: vorbis decoder destruction
+ * CloseDecoder: vorbis decoder destruction
*****************************************************************************/
-static int EndDecoder( decoder_t * p_dec )
+static void CloseDecoder( vlc_object_t *p_this )
{
+ decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_sys->p_aout_input != NULL )
- {
- aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
- }
-
- if( p_sys->p_sout_input != NULL )
- {
- sout_InputDelete( p_sys->p_sout_input );
- }
-
if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
{
vorbis_block_clear( &p_sys->vb );
vorbis_info_clear( &p_sys->vi ); /* must be called last */
free( p_sys );
-
- return VLC_SUCCESS;
}
-
#if defined(HAVE_VORBIS_VORBISENC_H) && !defined(MODULE_NAME_IS_tremor)
/*****************************************************************************
int i_samples_delay;
int i_channels;
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
-
/*
* Common properties
*/
encoder_t *p_enc = (encoder_t *)p_this;
encoder_sys_t *p_sys;
- if( p_enc->i_fourcc != VLC_FOURCC('v','o','r','b') )
+ if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') )
{
return VLC_EGENERIC;
}
p_enc->pf_header = Headers;
p_enc->pf_encode_audio = Encode;
- p_enc->format.audio.i_format = VLC_FOURCC('f','l','3','2');
+ p_enc->fmt_in.i_codec = VLC_FOURCC('f','l','3','2');
/* Initialize vorbis encoder */
vorbis_info_init( &p_sys->vi );
if( vorbis_encode_setup_managed( &p_sys->vi,
- aout_FormatNbChannels( &p_enc->format.audio ),
- p_enc->format.audio.i_rate, -1, p_enc->i_bitrate, -1 ) ||
+ p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate,
+ -1, p_enc->fmt_out.i_bitrate, -1 ) ||
vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
vorbis_encode_setup_init( &p_sys->vi ) ){}
vorbis_analysis_init( &p_sys->vd, &p_sys->vi );
vorbis_block_init( &p_sys->vd, &p_sys->vb );
- p_sys->i_channels = aout_FormatNbChannels( &p_enc->format.audio );
+ p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
p_sys->i_last_block_size = 0;
p_sys->i_samples_delay = 0;
p_sys->i_headers = 0;
p_sys->i_pts = p_aout_buf->start_date -
(mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
- (mtime_t)p_enc->format.audio.i_rate;
+ (mtime_t)p_enc->fmt_in.audio.i_rate;
p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
p_sys->i_last_block_size = i_block_size;
p_block->i_length = (mtime_t)1000000 *
- (mtime_t)i_samples / (mtime_t)p_enc->format.audio.i_rate;
+ (mtime_t)i_samples / (mtime_t)p_enc->fmt_in.audio.i_rate;
p_block->i_dts = p_block->i_pts = p_sys->i_pts;
* xvid.c: a decoder for libxvidcore, the Xvid video codec
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: xvid.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $
+ * $Id: xvid.c,v 1.7 2003/11/16 21:07:30 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
{
decoder_t *p_dec = (decoder_t*)p_this;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('x','v','i','d')
- && p_dec->p_fifo->i_fourcc != VLC_FOURCC('X','V','I','D')
- && p_dec->p_fifo->i_fourcc != VLC_FOURCC('D','I','V','X') )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC('x','v','i','d')
+ && p_dec->fmt_in.i_codec != VLC_FOURCC('X','V','I','D')
+ && p_dec->fmt_in.i_codec != VLC_FOURCC('D','I','V','X') )
{
return VLC_EGENERIC;
}
* a52.c : Raw a52 Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: a52sys.c,v 1.8 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: a52sys.c,v 1.9 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
{
int i_frame_size;
- HeaderInfo( p_peek, &fmt.audio.i_channels, &fmt.audio.i_samplerate, &i_frame_size );
+ HeaderInfo( p_peek, &fmt.audio.i_channels, &fmt.audio.i_rate, &i_frame_size );
msg_Dbg( p_input, "a52 channels=%d sample_rate=%d",
- fmt.audio.i_channels, fmt.audio.i_samplerate );
+ fmt.audio.i_channels, fmt.audio.i_rate );
}
vlc_mutex_lock( &p_input->stream.stream_lock );
* aac.c : Raw aac Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: aac.c,v 1.6 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: aac.c,v 1.7 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
if( HeaderCheck( p_peek ) )
{
fmt.audio.i_channels = AAC_CHANNELS( p_peek );
- fmt.audio.i_samplerate = AAC_SAMPLE_RATE( p_peek );
+ fmt.audio.i_rate = AAC_SAMPLE_RATE( p_peek );
msg_Dbg( p_input,
"adts header: id=%d channels=%d sample_rate=%d",
* asf.c : ASFv01 file input module for vlc
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
- * $Id: asf.c,v 1.40 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: asf.c,v 1.41 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
es_format_Init( &fmt, AUDIO_ES, 0 );
wf_tag_to_fourcc( GetWLE( &p_data[0] ), &fmt.i_codec, NULL );
fmt.audio.i_channels = GetWLE( &p_data[2] );
- fmt.audio.i_samplerate = GetDWLE( &p_data[4] );
+ fmt.audio.i_rate = GetDWLE( &p_data[4] );
fmt.audio.i_bitrate = GetDWLE( &p_data[8] ) * 8;
fmt.audio.i_blockalign = GetWLE( &p_data[12] );
fmt.audio.i_bitspersample = GetWLE( &p_data[14] );
* au.c : au file input module for vlc
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
- * $Id: au.c,v 1.8 2003/11/11 00:37:59 fenrir Exp $
+ * $Id: au.c,v 1.9 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
/* Create WAVEFORMATEX structure */
es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
p_sys->fmt.audio.i_channels = p_sys->au.i_channels;
- p_sys->fmt.audio.i_samplerate = p_sys->au.i_sample_rate;
+ p_sys->fmt.audio.i_rate = p_sys->au.i_sample_rate;
switch( p_sys->au.i_encoding )
{
case AU_ALAW_8: /* 8-bit ISDN A-law */
i_cat = AU_CAT_UNKNOWN;
goto error;
}
- p_sys->fmt.audio.i_bitrate = p_sys->fmt.audio.i_samplerate *
+ p_sys->fmt.audio.i_bitrate = p_sys->fmt.audio.i_rate *
p_sys->fmt.audio.i_channels *
p_sys->fmt.audio.i_bitspersample;
int i_samples, i_modulo;
/* read samples for 50ms of */
- i_samples = __MAX( p_sys->fmt.audio.i_samplerate / 20, 1 );
+ i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
p_sys->i_frame_size = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
p_sys->i_frame_length = (mtime_t)1000000 *
(mtime_t)i_samples /
- (mtime_t)p_sys->fmt.audio.i_samplerate;
+ (mtime_t)p_sys->fmt.audio.i_rate;
p_input->pf_demux = DemuxPCM;
p_input->pf_demux_control = demux_vaControlDefault;
* avi.c : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.68 2003/11/16 15:51:59 titer Exp $
+ * $Id: avi.c,v 1.69 2003/11/16 21:07:31 gbazin Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
fmt.audio.i_channels = p_auds->p_wf->nChannels;
- fmt.audio.i_samplerate = p_auds->p_wf->nSamplesPerSec;
+ fmt.audio.i_rate = p_auds->p_wf->nSamplesPerSec;
fmt.audio.i_bitrate = p_auds->p_wf->nAvgBytesPerSec * 8;
fmt.audio.i_blockalign = p_auds->p_wf->nBlockAlign;
fmt.audio.i_bitspersample = p_auds->p_wf->wBitsPerSample;
* live.cpp : live.com support.
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: livedotcom.cpp,v 1.6 2003/11/08 06:47:34 fenrir Exp $
+ * $Id: livedotcom.cpp,v 1.7 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
{
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'u', 'n', 'd', 'f' ) );
tk->fmt.audio.i_channels = sub->numChannels();
- tk->fmt.audio.i_samplerate = sub->rtpSource()->timestampFrequency();
+ tk->fmt.audio.i_rate = sub->rtpSource()->timestampFrequency();
if( !strcmp( sub->codecName(), "MPA" ) ||
!strcmp( sub->codecName(), "MPA-ROBUST" ) ||
!strcmp( sub->codecName(), "X-MP3-DRAFT-00" ) )
{
tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
- tk->fmt.audio.i_samplerate = 0;
+ tk->fmt.audio.i_rate = 0;
}
else if( !strcmp( sub->codecName(), "AC3" ) )
{
tk->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
- tk->fmt.audio.i_samplerate = 0;
+ tk->fmt.audio.i_rate = 0;
}
else if( !strcmp( sub->codecName(), "L16" ) )
{
* mkv.cpp : matroska demuxer
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: mkv.cpp,v 1.39 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: mkv.cpp,v 1.40 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)el4;
vwidth.ReadData( p_sys->es->I_O() );
- tk.fmt.video.i_display_width = uint16( vwidth );
+ tk.fmt.video.i_visible_width = uint16( vwidth );
msg_Dbg( p_input, "| | | | + display width=%d", uint16( vwidth ) );
}
else if( EbmlId( *el4 ) == KaxVideoDisplayHeight::ClassInfos.GlobalId )
KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)el4;
vheight.ReadData( p_sys->es->I_O() );
- tk.fmt.video.i_display_height = uint16( vheight );
+ tk.fmt.video.i_visible_height = uint16( vheight );
msg_Dbg( p_input, "| | | | + display height=%d", uint16( vheight ) );
}
else if( EbmlId( *el4 ) == KaxVideoFrameRate::ClassInfos.GlobalId )
KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)el4;
afreq.ReadData( p_sys->es->I_O() );
- tk.fmt.audio.i_samplerate = (int)float( afreq );
- msg_Dbg( p_input, "| | | | + afreq=%d", tk.fmt.audio.i_samplerate );
+ tk.fmt.audio.i_rate = (int)float( afreq );
+ msg_Dbg( p_input, "| | | | + afreq=%d", tk.fmt.audio.i_rate );
}
else if( EbmlId( *el4 ) == KaxAudioChannels::ClassInfos.GlobalId )
{
wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &tk.fmt.i_codec, NULL );
tk.fmt.audio.i_channels = GetWLE( &p_wf->nChannels );
- tk.fmt.audio.i_samplerate = GetDWLE( &p_wf->nSamplesPerSec );
+ tk.fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
tk.fmt.audio.i_bitrate = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
tk.fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
tk.fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
for( i_srate = 0; i_srate < 13; i_srate++ )
{
- if( i_sample_rates[i_srate] == tk.fmt.audio.i_samplerate )
+ if( i_sample_rates[i_srate] == tk.fmt.audio.i_rate )
{
break;
}
* mpga.c : MPEG-I/II Audio input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: mpga.c,v 1.7 2003/11/13 12:28:34 fenrir Exp $
+ * $Id: mpga.c,v 1.8 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
MPGA_SAMPLE_RATE( header ) );
fmt.audio.i_channels = MPGA_CHANNELS( header );
- fmt.audio.i_samplerate = MPGA_SAMPLE_RATE( header );
+ fmt.audio.i_rate = MPGA_SAMPLE_RATE( header );
fmt.audio.i_bitrate = p_sys->i_bitrate_avg;
}
* wav.c : wav file input module for vlc
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
- * $Id: wav.c,v 1.8 2003/11/11 02:49:26 fenrir Exp $
+ * $Id: wav.c,v 1.9 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_sys->fmt.i_codec, &psz_name );
p_sys->fmt.audio.i_channels = GetWLE ( &p_wf->nChannels );
- p_sys->fmt.audio.i_samplerate = GetDWLE( &p_wf->nSamplesPerSec );
+ p_sys->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
p_sys->fmt.audio.i_blockalign = GetWLE ( &p_wf->nBlockAlign );
p_sys->fmt.audio.i_bitrate = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
p_sys->fmt.audio.i_bitspersample = GetWLE ( &p_wf->wBitsPerSample );;
msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s blockalign:%d bits/samples:%d extra size:%d",
GetWLE( &p_wf->wFormatTag ),
p_sys->fmt.audio.i_channels,
- p_sys->fmt.audio.i_samplerate,
+ p_sys->fmt.audio.i_rate,
p_sys->fmt.audio.i_bitrate / 8 / 1024,
p_sys->fmt.audio.i_blockalign,
p_sys->fmt.audio.i_bitspersample,
int i_modulo;
/* read samples for 50ms of */
- i_samples = __MAX( p_sys->fmt.audio.i_samplerate / 20, 1 );
+ i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
*pi_length = (mtime_t)1000000 *
(mtime_t)i_samples /
- (mtime_t)p_sys->fmt.audio.i_samplerate;
+ (mtime_t)p_sys->fmt.audio.i_rate;
i_bytes = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
*pi_length = (mtime_t)1000000 *
(mtime_t)i_samples /
- (mtime_t)p_sys->fmt.audio.i_samplerate;
+ (mtime_t)p_sys->fmt.audio.i_rate;
*pi_size = p_sys->fmt.audio.i_blockalign;
}
*pi_length = (mtime_t)1000000 *
(mtime_t)i_samples /
- (mtime_t)p_sys->fmt.audio.i_samplerate;
+ (mtime_t)p_sys->fmt.audio.i_rate;
*pi_size = p_sys->fmt.audio.i_blockalign;
}
interface.c \
input.c \
decoder.c \
+ encoder.c \
renderer.c \
$(NULL)
/*****************************************************************************
- * dec_dummy.c: dummy decoder plugin for vlc.
+ * decoder.c: dummy decoder plugin for vlc.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: decoder.c,v 1.7 2003/10/25 00:49:14 sam Exp $
+ * $Id: decoder.c,v 1.8 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#include <stdio.h> /* sprintf() */
/*****************************************************************************
- * Local prototypes
+ * decoder_sys_t : theora decoder descriptor
*****************************************************************************/
-static int Run ( decoder_fifo_t * );
+struct decoder_sys_t
+{
+ int i_fd;
+};
/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************
- * Always returns 0 because we are the dummy decoder!
+ * Local prototypes
*****************************************************************************/
-int E_(OpenDecoder) ( vlc_object_t *p_this )
-{
- ((decoder_t*)p_this)->pf_run = Run;
-
- return VLC_SUCCESS;
-}
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
/*****************************************************************************
- * Run: this function is called just after the thread is created
+ * OpenDecoder: Open the decoder
*****************************************************************************/
-static int Run ( decoder_fifo_t *p_fifo )
+int E_(OpenDecoder) ( vlc_object_t *p_this )
{
- uint8_t p_buffer[1024];
+ decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
+ char psz_file[ PATH_MAX ];
- bit_stream_t bit_stream;
- mtime_t last_date = mdate();
- size_t i_bytes = 0;
+ /* Allocate the memory needed to store the decoder's structure */
+ if( ( p_dec->p_sys = p_sys =
+ (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
+ {
+ msg_Err( p_dec, "out of memory" );
+ return VLC_EGENERIC;
+ }
- char psz_file[100];
-#ifndef UNDER_CE
- int i_fd;
-#endif
+ sprintf( psz_file, "stream.%i", p_dec->i_object_id );
- sprintf( psz_file, "stream.%i", p_fifo->i_object_id );
#ifndef UNDER_CE
- i_fd = open( psz_file, O_WRONLY | O_CREAT | O_TRUNC, 00644 );
+ p_sys->i_fd = open( psz_file, O_WRONLY | O_CREAT | O_TRUNC, 00644 );
- if( i_fd == -1 )
+ if( p_sys->i_fd == -1 )
{
- msg_Err( p_fifo, "cannot create `%s'", psz_file );
- p_fifo->b_error = 1;
- DecoderError( p_fifo );
- return -1;
+ msg_Err( p_dec, "cannot create `%s'", psz_file );
+ return VLC_EGENERIC;
}
#endif
- msg_Dbg( p_fifo, "dumping stream to file `%s'", psz_file );
+ msg_Dbg( p_dec, "dumping stream to file `%s'", psz_file );
- if( InitBitstream( &bit_stream, p_fifo, NULL, NULL ) != VLC_SUCCESS )
- {
- msg_Err( p_fifo, "cannot initialize bitstream" );
- p_fifo->b_error = 1;
- DecoderError( p_fifo );
-#ifndef UNDER_CE
- close( i_fd );
-#endif
- return -1;
- }
+ /* Set callbacks */
+ p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
+ p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
+ DecodeBlock;
- while( !p_fifo->b_die && !p_fifo->b_error )
- {
- GetChunk( &bit_stream, p_buffer, 1024 );
-#ifndef UNDER_CE
- write( i_fd, p_buffer, 1024 );
+ return VLC_SUCCESS;
+}
- i_bytes += 1024;
-#endif
+/****************************************************************************
+ * RunDecoder: the whole thing
+ ****************************************************************************
+ * This function must be fed with ogg packets.
+ ****************************************************************************/
+static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
- if( mdate() < last_date + 2000000 )
- {
- continue;
- }
+ if( !pp_block || !*pp_block ) return NULL;
+ p_block = *pp_block;
- msg_Dbg( p_fifo, "dumped %i bytes", i_bytes );
+ if( p_block->i_buffer )
+ {
+#ifndef UNDER_CE
+ write( p_sys->i_fd, p_block->p_buffer, p_block->i_buffer );
+#endif
- i_bytes = 0;
- last_date = mdate();
+ msg_Dbg( p_dec, "dumped %i bytes", p_block->i_buffer );
}
- if( i_bytes )
- {
- msg_Dbg( p_fifo, "dumped %i bytes", i_bytes );
- }
+ block_Release( p_block );
+ return NULL;
+}
+
+/*****************************************************************************
+ * CloseDecoder: decoder destruction
+ *****************************************************************************/
+void E_(CloseDecoder) ( vlc_object_t *p_this )
+{
+ decoder_t *p_dec = (decoder_t *)p_this;
+ decoder_sys_t *p_sys = p_dec->p_sys;
#ifndef UNDER_CE
- close( i_fd );
+ close( p_sys->i_fd );
#endif
- CloseBitstream( &bit_stream );
-
- if( p_fifo->b_error )
- {
- DecoderError( p_fifo );
- return -1;
- }
- return 0;
+ free( p_sys );
}
* dummy.c : dummy plugin for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
- * $Id: dummy.c,v 1.9 2003/07/14 21:32:59 sigmunau Exp $
+ * $Id: dummy.c,v 1.10 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
add_submodule();
set_description( _("dummy decoder function") );
set_capability( "decoder", 0 );
- set_callbacks( E_(OpenDecoder), NULL );
+ set_callbacks( E_(OpenDecoder), E_(CloseDecoder) );
+ add_submodule();
+ set_description( _("dummy encoder function") );
+ set_capability( "encoder", 0 );
+ set_callbacks( E_(OpenEncoder), E_(CloseEncoder) );
add_submodule();
set_description( _("dummy audio output function") );
set_capability( "audio output", 1 );
* dummy.h : dummy plugin for vlc
*****************************************************************************
* Copyright (C) 2000, 2001, 2002 VideoLAN
- * $Id: dummy.h,v 1.2 2003/07/14 21:32:59 sigmunau Exp $
+ * $Id: dummy.h,v 1.3 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
void E_(CloseDemux) ( vlc_object_t * );
int E_(OpenDecoder) ( vlc_object_t * );
+void E_(CloseDecoder) ( vlc_object_t * );
+
+int E_(OpenEncoder) ( vlc_object_t * );
+void E_(CloseEncoder) ( vlc_object_t * );
int E_(OpenAudio) ( vlc_object_t * );
int E_(OpenVideo) ( vlc_object_t * );
-int E_(OpenRenderer) ( vlc_object_t * );
+int E_(OpenRenderer) ( vlc_object_t * );
* copy.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: copy.c,v 1.17 2003/09/29 22:37:36 gbazin Exp $
+ * $Id: copy.c,v 1.18 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
p_pack->output_format.i_cat = VIDEO_ES;
break;
- case VLC_FOURCC( 'I', '4', '2', '0' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'I', '4', '2', '0' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
- case VLC_FOURCC( 'I', '4', '2', '2' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'I', '4', '2', '2' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
- case VLC_FOURCC( 'R', 'V', '1', '5' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '5' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
- case VLC_FOURCC( 'R', 'V', '1', '6' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '6' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
- case VLC_FOURCC( 'R', 'V', '2', '4' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '2', '4' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
- case VLC_FOURCC( 'R', 'V', '3', '2' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'R', 'V', '3', '2' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
- case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
- p_pack->output_format.i_fourcc = VLC_FOURCC( 'G', 'R', 'E', 'Y' );
- p_pack->output_format.i_cat = VIDEO_ES;
- break;
-
/* audio */
case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'a' );
* mpeg4audio.c: parse and packetize an MPEG 4 audio stream
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4audio.c,v 1.11 2003/10/24 17:55:14 gbazin Exp $
+ * $Id: mpeg4audio.c,v 1.12 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
/*
* Input properties
*/
- int i_state;
+ int i_state;
- block_t *p_chain;
block_bytestream_t bytestream;
- /*
- * Packetizer output properties
- */
- sout_packetizer_input_t *p_sout_input;
- sout_format_t sout_format;
- sout_buffer_t * p_sout_buffer; /* current sout buffer */
-
/*
* Common properties
*/
- audio_date_t end_date;
- mtime_t pts;
+ audio_date_t end_date;
+ mtime_t i_pts;
int i_frame_size, i_raw_blocks;
unsigned int i_channels;
STATE_SYNC,
STATE_HEADER,
STATE_NEXT_SYNC,
- STATE_DATA
+ STATE_GET_DATA,
+ STATE_SEND_DATA
};
static int i_sample_rates[] =
/****************************************************************************
* Local prototypes
****************************************************************************/
-static int OpenPacketizer( vlc_object_t * );
-static int InitPacketizer( decoder_t * );
-static int RunFramePacketizer ( decoder_t *, block_t * );
-static int RunADTSPacketizer ( decoder_t *, block_t * );
-static int EndPacketizer ( decoder_t * );
-static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
+static int OpenPacketizer( vlc_object_t * );
+static void ClosePacketizer( vlc_object_t * );
+
+static block_t *PacketizeBlock ( decoder_t *, block_t ** );
+static block_t *ADTSPacketizeBlock( decoder_t *, block_t ** );
+
+static uint8_t *GetOutBuffer ( decoder_t *, void ** );
static int ADTSSyncInfo( decoder_t *, const byte_t * p_buf,
unsigned int * pi_channels,
vlc_module_begin();
set_description( _("MPEG4 Audio packetizer") );
set_capability( "packetizer", 50 );
- set_callbacks( OpenPacketizer, NULL );
+ set_callbacks( OpenPacketizer, ClosePacketizer );
vlc_module_end();
/*****************************************************************************
static int OpenPacketizer( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
+ if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
{
return VLC_EGENERIC;
}
/* Allocate the memory needed to store the decoder's structure */
- if( ( p_dec->p_sys =
+ if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
- p_dec->pf_init = InitPacketizer;
- p_dec->pf_decode = RunFramePacketizer;
- p_dec->pf_end = EndPacketizer;
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * InitPacketizer: Initalize the packetizer
- *****************************************************************************/
-static int InitPacketizer( decoder_t *p_dec )
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- WAVEFORMATEX *p_wf;
-
+ /* Misc init */
p_sys->i_state = STATE_NOSYNC;
-
aout_DateSet( &p_sys->end_date, 0 );
+ p_sys->bytestream = block_BytestreamInit( p_dec );
- p_sys->p_sout_input = NULL;
- p_sys->p_sout_buffer = NULL;
- p_sys->p_chain = NULL;
+ /* Set output properties */
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','4','a');
- msg_Info( p_dec, "Running MPEG4 audio packetizer" );
+ /* Set callback */
+ p_dec->pf_packetize = PacketizeBlock;
- p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex;
+ msg_Info( p_dec, "Running MPEG4 audio packetizer" );
- if( p_wf && p_wf->cbSize > 0)
+ if( p_dec->fmt_in.i_extra > 0 )
{
- uint8_t *p_config = (uint8_t*)&p_wf[1];
+ uint8_t *p_config = (uint8_t*)p_dec->fmt_in.p_extra;
int i_index;
i_index = ( ( p_config[0] << 1 ) | ( p_config[1] >> 7 ) ) & 0x0f;
if( i_index != 0x0f )
{
- p_sys->i_rate = i_sample_rates[i_index];
- p_sys->i_frame_length = (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
+ p_dec->fmt_out.audio.i_rate = i_sample_rates[i_index];
+ p_dec->fmt_out.audio.i_frame_length =
+ (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
}
else
{
- p_sys->i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
+ p_dec->fmt_out.audio.i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
( p_config[2] << 9 ) | ( p_config[3] << 1 ) |
( p_config[4] >> 7 );
- p_sys->i_frame_length = (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
+ p_dec->fmt_out.audio.i_frame_length =
+ (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
}
msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
- p_sys->i_rate, p_sys->i_frame_length );
+ p_dec->fmt_out.audio.i_rate,
+ p_dec->fmt_out.audio.i_frame_length );
- p_sys->i_channels = p_wf->nChannels;
- p_sys->sout_format.i_extra_data = p_wf->cbSize;
- p_sys->sout_format.p_extra_data = malloc( p_wf->cbSize );
- memcpy( p_sys->sout_format.p_extra_data, &p_wf[1], p_wf->cbSize );
+ aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+
+ p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
+ p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
+ p_dec->fmt_out.p_extra = malloc( p_dec->fmt_in.i_extra );
+ memcpy( p_dec->fmt_out.p_extra, p_dec->fmt_in.p_extra,
+ p_dec->fmt_in.i_extra );
}
else
{
msg_Dbg( p_dec, "No decoder specific info, must be an ADTS stream" );
/* We will try to create a AAC Config from adts */
- p_sys->sout_format.i_extra_data = 0;
- p_sys->sout_format.p_extra_data = NULL;
- p_dec->pf_decode = RunADTSPacketizer;
+ p_dec->fmt_out.i_extra = 0;
+ p_dec->fmt_out.p_extra = NULL;
+ p_dec->pf_packetize = ADTSPacketizeBlock;
}
return VLC_SUCCESS;
}
/****************************************************************************
- * RunFramePacketizer: the whole thing
+ * PacketizeBlock: the whole thing
****************************************************************************
* This function must be fed with complete frames.
****************************************************************************/
-static int RunFramePacketizer( decoder_t *p_dec, block_t *p_block )
+static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
+
+ if( !pp_block || !*pp_block ) return NULL;
+
+ p_block = *pp_block;
if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
{
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return VLC_SUCCESS;
+ return NULL;
}
-
- p_sys->pts = p_block->i_pts;
- p_sys->i_frame_size = p_block->i_buffer;
-
- if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
+ else if( p_block->i_pts != 0 &&
+ p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- return VLC_EGENERIC;
+ aout_DateSet( &p_sys->end_date, p_block->i_pts );
}
- /* Copy the whole frame into the buffer */
- p_dec->p_vlc->pf_memcpy( p_sys->p_sout_buffer->p_buffer,
- p_block->p_buffer, p_block->i_buffer );
+ p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
- sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
- p_sys->p_sout_buffer = NULL;
+ p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+ p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts;
- block_Release( p_block );
- return VLC_SUCCESS;
+ return *pp_block;
}
/****************************************************************************
- * RunADTSPacketizer: the whole thing
+ * DTSPacketizeBlock: the whole thing
****************************************************************************/
-static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
+static block_t *ADTSPacketizeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
uint8_t p_header[ADTS_HEADER_SIZE];
+ void *p_out_buffer;
+ uint8_t *p_buf;
- if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+ if( !pp_block || !*pp_block ) return NULL;
+
+ if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
{
/* We've just started the stream, wait for the first PTS. */
- block_Release( p_block );
- return VLC_SUCCESS;
+ block_Release( *pp_block );
+ return NULL;
}
- if( p_block->b_discontinuity )
+ if( (*pp_block)->b_discontinuity )
{
- p_sys->i_state = STATE_SYNC;
+ p_sys->i_state = STATE_NOSYNC;
}
- if( p_sys->p_chain )
- {
- block_ChainAppend( &p_sys->p_chain, p_block );
- }
- else
- {
- block_ChainAppend( &p_sys->p_chain, p_block );
- p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
- }
+ block_BytestreamPush( &p_sys->bytestream, *pp_block );
while( 1 )
{
}
if( p_sys->i_state != STATE_SYNC )
{
- if( block_PeekByte( &p_sys->bytestream, p_header )
- == VLC_SUCCESS && p_header[0] == 0xff )
- {
- /* Start of a sync word, need more data */
- return VLC_SUCCESS;
- }
-
- block_ChainRelease( p_sys->p_chain );
- p_sys->p_chain = NULL;
+ block_BytestreamFlush( &p_sys->bytestream );
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
case STATE_SYNC:
/* New frame, set the Presentation Time Stamp */
- p_sys->pts = p_sys->bytestream.p_block->i_pts;
- if( p_sys->pts != 0 &&
- p_sys->pts != aout_DateGet( &p_sys->end_date ) )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
+ if( p_sys->i_pts != 0 &&
+ p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
{
- aout_DateSet( &p_sys->end_date, p_sys->pts );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
p_sys->i_state = STATE_HEADER;
break;
ADTS_HEADER_SIZE ) != VLC_SUCCESS )
{
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
/* Check if frame is valid and get frame info */
break;
}
- p_sys->i_state = STATE_DATA;
+ p_sys->i_state = STATE_NEXT_SYNC;
- case STATE_DATA:
+ case STATE_NEXT_SYNC:
/* TODO: If p_block == NULL, flush the buffer without checking the
* next sync word */
!= VLC_SUCCESS )
{
/* Need more data */
- return VLC_SUCCESS;
+ return NULL;
}
if( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 )
break;
}
- if( !p_sys->p_sout_buffer )
- if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
+ p_sys->i_state = STATE_SEND_DATA;
+ break;
+
+ case STATE_GET_DATA:
+ /* Make sure we have enough data.
+ * (Not useful if we went through NEXT_SYNC) */
+ if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size +
+ p_sys->i_header_size) != VLC_SUCCESS )
{
- return VLC_EGENERIC;
+ /* Need more data */
+ return NULL;
}
+ p_sys->i_state = STATE_SEND_DATA;
- /* Skip the ADTS header */
- if( p_sys->i_header_size )
+ case STATE_SEND_DATA:
+ if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
{
- if( block_SkipBytes( &p_sys->bytestream,
- p_sys->i_header_size ) != VLC_SUCCESS )
- {
- /* Need more data */
- return VLC_SUCCESS;
- }
- p_sys->i_header_size = 0;
+ //p_dec->b_error = VLC_TRUE;
+ return NULL;
}
+ /* When we reach this point we already know we have enough
+ * data available. */
+
+ /* Skip the ADTS header */
+ block_SkipBytes( &p_sys->bytestream, p_sys->i_header_size );
+
/* Copy the whole frame into the buffer */
- if( block_GetBytes( &p_sys->bytestream,
- p_sys->p_sout_buffer->p_buffer,
- p_sys->i_frame_size ) != VLC_SUCCESS )
- {
- /* Need more data */
- return VLC_SUCCESS;
- }
+ block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
- p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
+ /* Make sure we don't reuse the same pts twice */
+ if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
+ p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
- sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
+ /* So p_block doesn't get re-added several times */
+ *pp_block = block_BytestreamPop( &p_sys->bytestream );
p_sys->i_state = STATE_NOSYNC;
- p_sys->p_sout_buffer = NULL;
- /* Make sure we don't reuse the same pts twice */
- if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
- p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
+ return p_out_buffer;
}
}
- return VLC_SUCCESS;
+ return NULL;
}
/*****************************************************************************
- * GetSoutBuffer:
+ * GetOutBuffer:
*****************************************************************************/
-static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
+static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
- if( p_sys->p_sout_input != NULL &&
- ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
- || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
- {
- /* Parameters changed - this should not happen. */
- }
-
- /* Creating the sout input if not created yet. */
- if( p_sys->p_sout_input == NULL )
+ if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
{
- p_sys->sout_format.i_cat = AUDIO_ES;
- p_sys->sout_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'a' );
- p_sys->sout_format.i_sample_rate = p_sys->i_rate;
- p_sys->sout_format.i_channels = p_sys->i_channels;
- p_sys->sout_format.i_block_align = 0;
- p_sys->sout_format.i_bitrate = 0;
-
- aout_DateInit( &p_sys->end_date, p_sys->i_rate );
- aout_DateSet( &p_sys->end_date, p_sys->pts );
-
- p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
- if( p_sys->p_sout_input == NULL )
- {
- msg_Err( p_dec, "cannot add a new stream" );
- *pp_buffer = NULL;
- return VLC_EGENERIC;
- }
msg_Info( p_dec, "AAC channels: %d samplerate: %d",
p_sys->i_channels, p_sys->i_rate );
- }
- *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
- p_sys->i_frame_size );
- if( *pp_buffer == NULL )
- {
- return VLC_EGENERIC;
+ aout_DateInit( &p_sys->end_date, p_sys->i_rate );
+ aout_DateSet( &p_sys->end_date, p_sys->i_pts );
}
- (*pp_buffer)->i_pts =
- (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
+ p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
+ p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
+ p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
+ p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
- (*pp_buffer)->i_length =
- aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length )
- - (*pp_buffer)->i_pts;
+#if 0
+ p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
+ p_dec->fmt_out.audio.i_physical_channels =
+ p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
+#endif
- return VLC_SUCCESS;
+ p_block = block_New( p_dec, p_sys->i_frame_size );
+ if( p_block == NULL ) return NULL;
+
+ p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
+
+ p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+ p_sys->i_frame_length ) - p_block->i_pts;
+
+ *pp_out_buffer = p_block;
+ return p_block->p_buffer;
}
/*****************************************************************************
- * EndPacketizer: clean up the packetizer
+ * ClosePacketizer: clean up the packetizer
*****************************************************************************/
-static int EndPacketizer( decoder_t *p_dec )
+static void ClosePacketizer( vlc_object_t *p_this )
{
- if( p_dec->p_sys->p_sout_input != NULL )
- {
- if( p_dec->p_sys->p_sout_buffer )
- {
- sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
- p_dec->p_sys->p_sout_buffer );
- }
-
- sout_InputDelete( p_dec->p_sys->p_sout_input );
- }
+ decoder_t *p_dec = (decoder_t *)p_this;
+ decoder_sys_t *p_sys = p_dec->p_sys;
- if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
+ block_BytestreamRelease( &p_sys->bytestream );
free( p_dec->p_sys );
-
- return VLC_SUCCESS;
}
/*****************************************************************************
unsigned int * pi_header_size,
unsigned int * pi_raw_blocks_in_frame )
{
- decoder_sys_t *p_sys = p_dec->p_sys;
int i_id, i_profile, i_sample_rate_idx, i_frame_size;
vlc_bool_t b_crc;
*pi_frame_length = 1024;
/* Build the decoder specific info header */
- if( !p_dec->p_sys->sout_format.i_extra_data )
+ if( !p_dec->fmt_out.i_extra )
{
- p_sys->sout_format.i_extra_data = 2;
- p_sys->sout_format.p_extra_data = malloc( 2 );
- p_sys->sout_format.p_extra_data[0] =
+ p_dec->fmt_out.i_extra = 2;
+ p_dec->fmt_out.p_extra = malloc( 2 );
+ ((uint8_t *)p_dec->fmt_out.p_extra)[0] =
(i_profile + 1) << 3 | (i_sample_rate_idx >> 1);
- p_sys->sout_format.p_extra_data[1] =
+ ((uint8_t *)p_dec->fmt_out.p_extra)[1] =
((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
}
* transcode.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: transcode.c,v 1.49 2003/11/05 18:59:01 gbazin Exp $
+ * $Id: transcode.c,v 1.50 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
}
}
+static inline vlc_fourcc_t get_vlc_chroma( int i_pix_fmt )
+{
+ switch( i_pix_fmt )
+ {
+ case PIX_FMT_YUV420P:
+ return VLC_FOURCC('I','4','2','0');
+ case PIX_FMT_YUV422P:
+ return VLC_FOURCC('I','4','2','2');
+ case PIX_FMT_YUV444P:
+ return VLC_FOURCC('I','4','4','4');
+
+ case PIX_FMT_YUV422:
+ return VLC_FOURCC('Y','U','Y','2');
+
+ case PIX_FMT_RGB555:
+ return VLC_FOURCC('R','V','1','5');
+ case PIX_FMT_RGB565:
+ return VLC_FOURCC('R','V','1','6');
+ case PIX_FMT_RGB24:
+ return VLC_FOURCC('R','V','2','4');
+ case PIX_FMT_RGBA32:
+ return VLC_FOURCC('R','V','3','2');
+ case PIX_FMT_GRAY8:
+ return VLC_FOURCC('G','R','E','Y');
+
+ case PIX_FMT_YUV410P:
+ case PIX_FMT_YUV411P:
+ case PIX_FMT_BGR24:
+ default:
+ return 0;
+ }
+}
+
static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
sout_stream_id_t *id )
{
/* find encoder */
id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
- id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
- id->p_encoder->format.audio.i_format = AOUT_FMT_S16_NE;
- id->p_encoder->format.audio.i_rate = id->f_dst.i_sample_rate;
- id->p_encoder->format.audio.i_physical_channels =
- id->p_encoder->format.audio.i_original_channels =
+
+ /* Initialization of encoder format structures */
+ es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE );
+ id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE;
+ id->p_encoder->fmt_in.audio.i_rate = id->f_dst.i_sample_rate;
+ id->p_encoder->fmt_in.audio.i_physical_channels =
+ id->p_encoder->fmt_in.audio.i_original_channels =
pi_channels_maps[id->f_dst.i_channels];
- id->p_encoder->i_bitrate = id->f_dst.i_bitrate;
- id->p_encoder->i_extra_data = 0;
- id->p_encoder->p_extra_data = NULL;
+ id->p_encoder->fmt_in.audio.i_channels = id->f_dst.i_channels;
+
+ id->p_encoder->fmt_out = id->p_encoder->fmt_in;
+ id->p_encoder->fmt_out.i_codec = id->f_dst.i_fourcc;
+ id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
id->p_encoder->p_module =
- module_Need( id->p_encoder, "audio encoder", NULL );
+ module_Need( id->p_encoder, "encoder", NULL );
if( !id->p_encoder->p_module )
{
vlc_object_destroy( id->p_encoder );
id->b_enc_inited = VLC_FALSE;
- id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
- id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
+ id->f_dst.i_extra_data = id->p_encoder->fmt_out.i_extra;
+ id->f_dst.p_extra_data = id->p_encoder->fmt_out.p_extra;
/* Hack for mp3 transcoding support */
if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
/* Open encoder */
id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
- id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
- id->p_encoder->format.video.i_width = p_sys->i_width;
- id->p_encoder->format.video.i_height = p_sys->i_height;
- id->p_encoder->i_bitrate = p_sys->i_vbitrate;
- id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
- id->p_encoder->i_key_int = p_sys->i_key_int;
- id->p_encoder->i_b_frames = p_sys->i_b_frames;
- id->p_encoder->i_qmin = p_sys->i_qmin;
- id->p_encoder->i_qmax = p_sys->i_qmax;
- id->p_encoder->i_hq = p_sys->i_hq;
+ /* Initialization of encoder format structures */
+ es_format_Init( &id->p_encoder->fmt_in,
+ id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
+
+ id->p_encoder->fmt_in.video.i_width = id->f_dst.i_width;
+ id->p_encoder->fmt_in.video.i_height = id->f_dst.i_height;
- if( id->p_encoder->format.video.i_width <= 0 )
+ if( id->p_encoder->fmt_in.video.i_width <= 0 )
{
- id->p_encoder->format.video.i_width = id->f_dst.i_width =
+ id->p_encoder->fmt_in.video.i_width = id->f_dst.i_width =
id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
}
- if( id->p_encoder->format.video.i_height <= 0 )
+ if( id->p_encoder->fmt_in.video.i_height <= 0 )
{
- id->p_encoder->format.video.i_height = id->f_dst.i_height =
+ id->p_encoder->fmt_in.video.i_height = id->f_dst.i_height =
id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
}
- id->p_ff_pic = avcodec_alloc_frame();
- id->p_ff_pic_tmp0 = NULL;
- id->p_ff_pic_tmp1 = NULL;
- id->p_ff_pic_tmp2 = NULL;
- id->p_vresample = NULL;
-
+ id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
+ id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
if( id->ff_dec )
{
- id->p_encoder->i_frame_rate = id->ff_dec_c->frame_rate;
+ id->p_encoder->fmt_in.video.i_frame_rate = id->ff_dec_c->frame_rate;
#if LIBAVCODEC_BUILD >= 4662
- id->p_encoder->i_frame_rate_base= id->ff_dec_c->frame_rate_base;
+ id->p_encoder->fmt_in.video.i_frame_rate_base =
+ id->ff_dec_c->frame_rate_base;
#endif
#if LIBAVCODEC_BUILD >= 4687
- id->p_encoder->i_aspect = VOUT_ASPECT_FACTOR *
+ id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
id->ff_dec_c->width / id->ff_dec_c->height );
#else
- id->p_encoder->i_aspect = VOUT_ASPECT_FACTOR *
+ id->p_encoder->video.fmt_in.i_aspect = VOUT_ASPECT_FACTOR *
id->ff_dec_c->aspect_ratio;
#endif
}
- else
- {
-#if LIBAVCODEC_BUILD >= 4662
- id->p_encoder->i_frame_rate = 25 ; /* FIXME as it break mpeg */
- id->p_encoder->i_frame_rate_base= 1;
-#else
- id->p_encoder->i_frame_rate = 25 * FRAME_RATE_BASE;
-#endif
- }
+
+ id->p_encoder->fmt_out = id->p_encoder->fmt_in;
+ id->p_encoder->fmt_out.i_codec = id->f_dst.i_fourcc;
+ id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
+
+ id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
+ id->p_encoder->i_key_int = p_sys->i_key_int;
+ id->p_encoder->i_b_frames = p_sys->i_b_frames;
+ id->p_encoder->i_qmin = p_sys->i_qmin;
+ id->p_encoder->i_qmax = p_sys->i_qmax;
+ id->p_encoder->i_hq = p_sys->i_hq;
+
+ id->p_ff_pic = avcodec_alloc_frame();
+ id->p_ff_pic_tmp0 = NULL;
+ id->p_ff_pic_tmp1 = NULL;
+ id->p_ff_pic_tmp2 = NULL;
+ id->p_vresample = NULL;
id->p_encoder->p_module =
- module_Need( id->p_encoder, "video encoder", NULL );
+ module_Need( id->p_encoder, "encoder", NULL );
if( !id->p_encoder->p_module )
{
{
/* XXX hack because of copy packetizer and mpeg4video that can fail
* detecting size */
- if( id->p_encoder->format.video.i_width <= 0 )
+ if( id->p_encoder->fmt_in.video.i_width <= 0 )
{
- id->p_encoder->format.video.i_width = id->f_dst.i_width =
+ id->p_encoder->fmt_in.video.i_width =
+ id->p_encoder->fmt_out.video.i_width = id->f_dst.i_width =
id->ff_dec_c->width - p_sys->i_crop_left -
- p_sys->i_crop_right;
+ p_sys->i_crop_right;
}
- if( id->p_encoder->format.video.i_height <= 0 )
+ if( id->p_encoder->fmt_in.video.i_height <= 0 )
{
- id->p_encoder->format.video.i_height = id->f_dst.i_height =
+ id->p_encoder->fmt_in.video.i_height =
+ id->p_encoder->fmt_out.video.i_height = id->f_dst.i_height =
id->ff_dec_c->height - p_sys->i_crop_top -
- p_sys->i_crop_bottom;
+ p_sys->i_crop_bottom;
}
- id->p_encoder->i_bitrate = p_sys->i_vbitrate;
-
- id->p_encoder->i_extra_data = 0;
- id->p_encoder->p_extra_data = NULL;
+ id->p_encoder->fmt_out.i_extra = 0;
+ id->p_encoder->fmt_out.p_extra = NULL;
id->p_encoder->p_module =
- module_Need( id->p_encoder, "video encoder", NULL );
+ module_Need( id->p_encoder, "encoder", NULL );
if( !id->p_encoder->p_module )
{
vlc_object_destroy( id->p_encoder );
return VLC_EGENERIC;
}
- id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
- id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
+ id->f_dst.i_extra_data = id->p_encoder->fmt_out.i_extra;
+ id->f_dst.p_extra_data = id->p_encoder->fmt_out.p_extra;
/* Hack for mp2v/mp1v transcoding support */
if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
}
id->i_inter_pixfmt =
- get_ff_chroma( id->p_encoder->format.video.i_chroma );
+ get_ff_chroma( id->p_encoder->fmt_in.i_codec );
id->b_enc_inited = VLC_TRUE;
}
/* Encoding */
vout_InitPicture( VLC_OBJECT(p_stream), &pic,
- id->p_encoder->format.video.i_chroma,
+ id->p_encoder->fmt_in.i_codec,
id->f_dst.i_width, id->f_dst.i_height,
id->f_dst.i_width * VOUT_ASPECT_FACTOR /
id->f_dst.i_height );
* common.c : audio output management of common data structures
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: common.c,v 1.17 2003/02/11 11:16:04 massiot Exp $
+ * $Id: common.c,v 1.18 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
val.b_bool = VLC_TRUE;
var_Set( p_aout, "intf-change", val );
- vlc_object_attach( p_aout, p_parent->p_vlc );
-
return p_aout;
}
* dec.c : audio output API towards decoders
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: dec.c,v 1.12 2003/10/27 21:54:10 gbazin Exp $
+ * $Id: dec.c,v 1.13 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
{
return NULL;
}
+ vlc_object_attach( *pp_aout, p_this->p_vlc );
}
else
{
* decoders.
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.254 2003/11/13 13:31:12 fenrir Exp $
+ * $Id: input.c,v 1.255 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
vlc_bool_t i_audio;
vlc_bool_t i_video;
};
+
struct es_out_id_t
{
es_descriptor_t *p_es;
out->p_sys->i_video = -1;
return out;
}
+
static void EsOutRelease( es_out_t *out )
{
es_out_sys_t *p_sys = out->p_sys;
{
case AUDIO_ES:
{
- WAVEFORMATEX *p_wf = malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
+ WAVEFORMATEX *p_wf =
+ malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
p_wf->nChannels = fmt->audio.i_channels;
- p_wf->nSamplesPerSec = fmt->audio.i_samplerate;
+ p_wf->nSamplesPerSec = fmt->audio.i_rate;
p_wf->nAvgBytesPerSec = fmt->audio.i_bitrate / 8;
p_wf->nBlockAlign = fmt->audio.i_blockalign;
p_wf->wBitsPerSample = fmt->audio.i_bitspersample;
{
if( fmt->i_extra_type != ES_EXTRA_TYPE_WAVEFORMATEX )
{
- msg_Warn( p_input, "extra type != WAVEFORMATEX for audio" );
+ msg_Warn( p_input, "extra type != WAVEFORMATEX for audio");
}
memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
}
p_bih->biPlanes = 1;
p_bih->biBitCount = 24;
p_bih->biCompression = fmt->i_codec;
- p_bih->biSizeImage = fmt->video.i_width * fmt->video.i_height;
+ p_bih->biSizeImage = fmt->video.i_width *
+ fmt->video.i_height;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
{
case AUDIO_ES:
input_AddInfo( p_cat, _("Type"), _("Audio") );
- input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&fmt->i_codec );
+ input_AddInfo( p_cat, _("Codec"), "%.4s",
+ (char*)&fmt->i_codec );
if( fmt->audio.i_channels > 0 )
{
- input_AddInfo( p_cat, _("Channels"), "%d", fmt->audio.i_channels );
+ input_AddInfo( p_cat, _("Channels"), "%d",
+ fmt->audio.i_channels );
}
- if( fmt->audio.i_samplerate > 0 )
+ if( fmt->audio.i_rate > 0 )
{
- input_AddInfo( p_cat, _("Sample Rate"), "%d", fmt->audio.i_samplerate );
+ input_AddInfo( p_cat, _("Sample Rate"), "%d",
+ fmt->audio.i_rate );
}
if( fmt->audio.i_bitrate > 0 )
{
- input_AddInfo( p_cat, _("Bitrate"), "%d", fmt->audio.i_bitrate );
+ input_AddInfo( p_cat, _("Bitrate"), "%d",
+ fmt->audio.i_bitrate );
}
if( fmt->audio.i_bitspersample )
{
- input_AddInfo( p_cat, _("Bits Per Sample"), "%d", fmt->audio.i_bitspersample );
+ input_AddInfo( p_cat, _("Bits Per Sample"), "%d",
+ fmt->audio.i_bitspersample );
}
break;
case VIDEO_ES:
input_AddInfo( p_cat, _("Type"), _("Video") );
- input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&fmt->i_codec );
+ input_AddInfo( p_cat, _("Codec"), "%.4s",
+ (char*)&fmt->i_codec );
if( fmt->video.i_width > 0 && fmt->video.i_height > 0 )
{
- input_AddInfo( p_cat, _("Resolution"), "%dx%d", fmt->video.i_width, fmt->video.i_height );
+ input_AddInfo( p_cat, _("Resolution"), "%dx%d",
+ fmt->video.i_width, fmt->video.i_height );
}
- if( fmt->video.i_display_width > 0 && fmt->video.i_display_height > 0 )
+ if( fmt->video.i_visible_width > 0 &&
+ fmt->video.i_visible_height > 0 )
{
- input_AddInfo( p_cat, _("Display Resolution"), "%dx%d", fmt->video.i_display_width, fmt->video.i_display_height);
+ input_AddInfo( p_cat, _("Display Resolution"), "%dx%d",
+ fmt->video.i_visible_width,
+ fmt->video.i_visible_height);
}
break;
case SPU_ES:
input_AddInfo( p_cat, _("Type"), _("Subtitle") );
- input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&fmt->i_codec );
+ input_AddInfo( p_cat, _("Codec"), "%.4s",
+ (char*)&fmt->i_codec );
break;
default:
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
+ id->p_es->fmt = *fmt;
+
TAB_APPEND( out->p_sys->i_id, out->p_sys->id, id );
return id;
}
+
static int EsOutSend( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes )
{
if( id->p_es->p_decoder_fifo )
}
return VLC_SUCCESS;
}
+
static void EsOutDel( es_out_t *out, es_out_id_t *id )
{
es_out_sys_t *p_sys = out->p_sys;
free( id );
}
+
static int EsOutControl( es_out_t *out, int i_query, va_list args )
{
es_out_sys_t *p_sys = out->p_sys;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_seek =
- (int64_t)( newval.f_float *
- (double)p_input->stream.p_selected_area->i_size );
+ (int64_t)( newval.f_float *
+ (double)p_input->stream.p_selected_area->i_size );
if( p_input->stream.p_selected_area->i_seek < 0 )
{
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.66 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: input_dec.c,v 1.67 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
+ * 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
#include <vlc/vlc.h>
#include <vlc/decoder.h>
+#include <vlc/vout.h>
+
+#include "stream_output.h"
#include "input_ext-intf.h"
#include "input_ext-plugins.h"
+#include "codecs.h"
+
static decoder_t * CreateDecoder( input_thread_t *, es_descriptor_t *, int );
static int DecoderThread( decoder_t * );
static void DeleteDecoder( decoder_t * );
+/* Buffers allocation callbacks for the decoders */
+static aout_buffer_t *aout_new_buffer( decoder_t *, int );
+static void aout_del_buffer( decoder_t *, aout_buffer_t * );
+
+static picture_t *vout_new_buffer( decoder_t * );
+static void vout_del_buffer( decoder_t *, picture_t * );
+
+static es_format_t null_es_format = {0};
+
/*****************************************************************************
* input_RunDecoder: spawns a new decoder thread
*****************************************************************************/
}
}
+struct decoder_owner_sys_t
+{
+ aout_instance_t *p_aout;
+ aout_input_t *p_aout_input;
+
+ vout_thread_t *p_vout;
+
+ sout_packetizer_input_t *p_sout;
+
+ /* Current format in use by the output */
+ video_format_t video;
+ audio_format_t audio;
+};
+
/*****************************************************************************
- * CreateDecoderFifo: create a decoder_fifo_t
+ * CreateDecoder: create a decoder object
*****************************************************************************/
static decoder_t * CreateDecoder( input_thread_t * p_input,
es_descriptor_t * p_es, int i_object_type )
{
- decoder_t * p_dec;
+ decoder_t *p_dec;
p_dec = vlc_object_create( p_input, i_object_type );
if( p_dec == NULL )
return NULL;
}
- p_dec->pf_init = 0;
p_dec->pf_decode = 0;
- p_dec->pf_end = 0;
+ p_dec->pf_decode_audio = 0;
+ p_dec->pf_decode_video = 0;
+ p_dec->pf_decode_sub = 0;
+ p_dec->pf_packetize = 0;
p_dec->pf_run = 0;
/* Select a new ES */
p_es );
/* Allocate the memory needed to store the decoder's fifo */
- //p_dec->p_fifo = (decoder_fifo_t *)malloc(sizeof(decoder_fifo_t));
p_dec->p_fifo = vlc_object_create( p_input, VLC_OBJECT_DECODER_FIFO );
if( p_dec->p_fifo == NULL )
{
}
/* Initialize the decoder fifo */
- //memset( p_dec->p_fifo, 0, sizeof(decoder_fifo_t) );
p_dec->p_module = NULL;
- /* Initialize the p_fifo structure */
+ p_dec->fmt_in = p_es->fmt;
+
+ if( p_es->p_waveformatex )
+ {
+#define p_wf ((WAVEFORMATEX *)p_es->p_waveformatex)
+ p_dec->fmt_in.audio.i_channels = p_wf->nChannels;
+ p_dec->fmt_in.audio.i_rate = p_wf->nSamplesPerSec;
+ p_dec->fmt_in.i_bitrate = p_wf->nAvgBytesPerSec * 8;
+ p_dec->fmt_in.audio.i_blockalign = p_wf->nBlockAlign;
+ p_dec->fmt_in.audio.i_bitspersample = p_wf->wBitsPerSample;
+ p_dec->fmt_in.i_extra = p_wf->cbSize;
+ p_dec->fmt_in.p_extra = NULL;
+ if( p_wf->cbSize )
+ {
+ p_dec->fmt_in.p_extra = malloc( p_wf->cbSize );
+ memcpy( p_dec->fmt_in.p_extra, &p_wf[1], p_wf->cbSize );
+ }
+ }
+
+ if( p_es->p_bitmapinfoheader )
+ {
+#define p_bih ((BITMAPINFOHEADER *) p_es->p_bitmapinfoheader)
+ p_dec->fmt_in.i_extra = p_bih->biSize - sizeof(BITMAPINFOHEADER);
+ p_dec->fmt_in.p_extra = NULL;
+ if( p_dec->fmt_in.i_extra )
+ {
+ p_dec->fmt_in.p_extra = malloc( p_dec->fmt_in.i_extra );
+ memcpy( p_dec->fmt_in.p_extra, &p_bih[1], p_dec->fmt_in.i_extra );
+ }
+
+ p_dec->fmt_in.video.i_width = p_bih->biWidth;
+ p_dec->fmt_in.video.i_height = p_bih->biHeight;
+ }
+
+ p_dec->fmt_in.i_cat = p_es->i_cat;
+ p_dec->fmt_in.i_codec = p_es->i_fourcc;
+
+ p_dec->fmt_out = null_es_format;
+
+ /* Allocate our private structure for the decoder */
+ p_dec->p_owner = (decoder_owner_sys_t*)malloc(sizeof(decoder_owner_sys_t));
+ if( p_dec->p_owner == NULL )
+ {
+ msg_Err( p_dec, "out of memory" );
+ return NULL;
+ }
+ p_dec->p_owner->p_aout = NULL;
+ p_dec->p_owner->p_aout_input = NULL;
+ p_dec->p_owner->p_vout = NULL;
+ p_dec->p_owner->p_sout = NULL;
+
+ /* Set buffers allocation callbacks for the decoders */
+ p_dec->pf_aout_buffer_new = aout_new_buffer;
+ p_dec->pf_aout_buffer_del = aout_del_buffer;
+ p_dec->pf_vout_buffer_new = vout_new_buffer;
+ p_dec->pf_vout_buffer_del = vout_del_buffer;
+
+ /* For old decoders only */
vlc_mutex_init( p_input, &p_dec->p_fifo->data_lock );
vlc_cond_init( p_input, &p_dec->p_fifo->data_wait );
p_es->p_decoder_fifo = p_dec->p_fifo;
-
p_dec->p_fifo->i_id = p_es->i_id;
p_dec->p_fifo->i_fourcc = p_es->i_fourcc;
p_dec->p_fifo->p_demux_data = p_es->p_demux_data;
p_dec->p_fifo->p_spuinfo = p_es->p_spuinfo;
p_dec->p_fifo->p_stream_ctrl = &p_input->stream.control;
p_dec->p_fifo->p_sout = p_input->stream.p_sout;
-
p_dec->p_fifo->p_first = NULL;
p_dec->p_fifo->pp_last = &p_dec->p_fifo->p_first;
p_dec->p_fifo->i_depth = 0;
p_dec->p_fifo->b_die = p_dec->p_fifo->b_error = 0;
p_dec->p_fifo->p_packets_mgt = p_input->p_method_data;
-
p_dec->p_fifo->p_dec = p_dec;
-
vlc_object_attach( p_dec->p_fifo, p_input );
+
vlc_object_attach( p_dec, p_input );
return p_dec;
return 0;
}
-
- /* Initialize the decoder */
- p_dec->p_fifo->b_error = p_dec->pf_init( p_dec );
-
/* The decoder's main loop */
while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
{
p_block->i_pts = p_pes->i_pts;
p_block->i_dts = p_pes->i_dts;
p_block->b_discontinuity = p_pes->b_discontinuity;
- p_dec->p_fifo->b_error = p_dec->pf_decode( p_dec, p_block );
- input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
- }
+ if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
+ {
+ sout_buffer_t *p_sout_buffer;
+ block_t *p_sout_block;
- /* If b_error is set, the decoder thread enters the error loop */
- if( p_dec->p_fifo->b_error )
- {
- /* Wait until a `die' order is sent */
- while( !p_dec->p_fifo->b_die )
+ while( (p_sout_block = p_dec->pf_packetize( p_dec, &p_block )) )
+ {
+ if( !p_dec->p_owner->p_sout )
+ {
+ sout_format_t sout_format;
+
+ sout_format.i_cat = p_dec->fmt_out.i_cat;
+ sout_format.i_fourcc = p_dec->fmt_out.i_codec;
+ sout_format.i_sample_rate =
+ p_dec->fmt_out.audio.i_rate;
+ sout_format.i_channels =
+ p_dec->fmt_out.audio.i_channels;
+ sout_format.i_width =
+ p_dec->fmt_out.video.i_width;
+ sout_format.i_height =
+ p_dec->fmt_out.video.i_height;
+ sout_format.i_block_align = 0;
+ //sout_format.i_bitrate = p_dec->fmt_out.i_bit_rate;
+ sout_format.i_extra_data = p_dec->fmt_out.i_extra;
+ sout_format.p_extra_data = p_dec->fmt_out.p_extra;
+
+ p_dec->p_owner->p_sout =
+ sout_InputNew( p_dec, &sout_format );
+
+ if( p_dec->p_owner->p_sout == NULL )
+ {
+ msg_Err( p_dec, "cannot create packetizer output" );
+ break;
+ }
+ }
+
+ p_sout_buffer =
+ sout_BufferNew( p_dec->p_owner->p_sout->p_sout,
+ p_sout_block->i_buffer );
+ if( p_sout_buffer == NULL )
+ {
+ msg_Err( p_dec, "cannot get sout buffer" );
+ break;
+ }
+
+ memcpy( p_sout_buffer->p_buffer, p_sout_block->p_buffer,
+ p_sout_block->i_buffer );
+
+ p_sout_buffer->i_pts = p_sout_block->i_pts;
+ p_sout_buffer->i_dts = p_sout_block->i_dts;
+ p_sout_buffer->i_length = p_sout_block->i_length;
+
+ block_Release( p_sout_block );
+
+ sout_InputSendBuffer( p_dec->p_owner->p_sout, p_sout_buffer );
+ }
+ }
+ else if( p_dec->fmt_in.i_cat == AUDIO_ES )
{
- /* Trash all received PES packets */
- input_ExtractPES( p_dec->p_fifo, NULL );
+ aout_buffer_t *p_aout_buf;
+
+ while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
+ {
+ aout_DecPlay( p_dec->p_owner->p_aout,
+ p_dec->p_owner->p_aout_input, p_aout_buf );
+ }
}
- }
+ else
+ {
+ picture_t *p_pic;
- /* End of the decoder */
- p_dec->pf_end( p_dec );
+ while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
+ {
+ vout_DatePicture( p_dec->p_owner->p_vout, p_pic, p_pic->date );
+ vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
+ }
+ }
+
+ input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
+ }
return 0;
}
/*****************************************************************************
- * DeleteDecoderFifo: destroy a decoder_fifo_t
+ * DeleteDecoder: destroys a decoder object
*****************************************************************************/
static void DeleteDecoder( decoder_t * p_dec )
{
/* Free fifo */
vlc_object_destroy( p_dec->p_fifo );
- //free( p_dec->p_fifo );
+
+ /* Cleanup */
+ if( p_dec->p_owner->p_aout_input )
+ aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );
+
+ if( p_dec->p_owner->p_vout )
+ {
+ int i_pic;
+
+ /* Hack to make sure all the the pictures are freed by the decoder */
+ for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
+ i_pic++ )
+ {
+ if( p_dec->p_owner->p_vout->render.pp_picture[i_pic]->i_status ==
+ RESERVED_PICTURE )
+ vout_DestroyPicture( p_dec->p_owner->p_vout,
+ p_dec->p_owner->p_vout->render.pp_picture[i_pic] );
+ if( p_dec->p_owner->p_vout->render.pp_picture[i_pic]->i_refcount
+ > 0 )
+ vout_UnlinkPicture( p_dec->p_owner->p_vout,
+ p_dec->p_owner->p_vout->render.pp_picture[i_pic] );
+ }
+
+ /* We are about to die. Reattach video output to p_vlc. */
+ vout_Request( p_dec, p_dec->p_owner->p_vout, 0, 0, 0, 0 );
+ }
+
+ if( p_dec->p_owner->p_sout )
+ sout_InputDelete( p_dec->p_owner->p_sout );
+
+ free( p_dec->p_owner );
+
+}
+
+/*****************************************************************************
+ * Buffers allocation callbacks for the decoders
+ *****************************************************************************/
+static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
+{
+ decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
+ aout_buffer_t *p_buffer;
+
+ if( p_sys->p_aout_input != NULL &&
+ ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||
+ p_dec->fmt_out.audio.i_original_channels !=
+ p_sys->audio.i_original_channels ||
+ p_dec->fmt_out.audio.i_bytes_per_frame !=
+ p_sys->audio.i_bytes_per_frame ) )
+ {
+ /* Parameters changed, restart the aout */
+ aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+ p_sys->p_aout_input = NULL;
+ }
+
+ if( p_sys->p_aout_input == NULL )
+ {
+ p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
+ p_sys->audio = p_dec->fmt_out.audio;
+ p_sys->p_aout_input =
+ aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->audio );
+ if( p_sys->p_aout_input == NULL )
+ {
+ msg_Err( p_dec, "failed to create audio output" );
+ return NULL;
+ }
+ p_dec->fmt_out.audio.i_bytes_per_frame =
+ p_sys->audio.i_bytes_per_frame;
+ }
+
+ p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
+ i_samples );
+
+ return p_buffer;
+}
+
+static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
+{
+ aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
+ p_dec->p_owner->p_aout_input, p_buffer );
+}
+
+static picture_t *vout_new_buffer( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
+ picture_t *p_pic;
+
+ if( p_sys->p_vout == NULL ||
+ p_dec->fmt_out.video.i_width != p_sys->video.i_width ||
+ p_dec->fmt_out.video.i_height != p_sys->video.i_height ||
+ p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||
+ p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )
+ {
+ if( !p_dec->fmt_out.video.i_width ||
+ !p_dec->fmt_out.video.i_height )
+ {
+ /* Can't create a new vout without display size */
+ return NULL;
+ }
+
+ p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
+ p_sys->video = p_dec->fmt_out.video;
+
+ p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
+ p_sys->video.i_width,
+ p_sys->video.i_height,
+ p_sys->video.i_chroma,
+ p_sys->video.i_aspect );
+
+ if( p_sys->p_vout == NULL )
+ {
+ msg_Err( p_dec, "failed to create video output" );
+ return NULL;
+ }
+ }
+
+ /* Get a new picture */
+ while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+ {
+ if( p_dec->b_die || p_dec->b_error )
+ {
+ return NULL;
+ }
+ msleep( VOUT_OUTMEM_SLEEP );
+ }
+
+ return p_pic;
+}
+
+static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
+{
+ vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
}
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999-2002 VideoLAN
- * $Id: input_programs.c,v 1.120 2003/11/06 16:36:41 nitrox Exp $
+ * $Id: input_programs.c,v 1.121 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
static int ESCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
+static es_format_t null_es_format = {0};
+
/*****************************************************************************
* input_InitStream: init the stream descriptor of the given input
*****************************************************************************/
p_es->c_packets = 0;
p_es->c_invalid_packets = 0;
p_es->b_force_decoder = VLC_FALSE;
+ p_es->fmt = null_es_format;
if( i_data_len )
{
* libvlc.h: main libvlc header
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.h,v 1.106 2003/11/15 00:26:15 hartman Exp $
+ * $Id: libvlc.h,v 1.107 2003/11/16 21:07:31 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
"its codecs (decompression methods). Only advanced users should " \
"alter this option as it can break playback of all your streams." )
-#define CODEC_TEXT N_("Choose preferred codec list")
+#define CODEC_TEXT N_("Choose preferred codecs list")
#define CODEC_LONGTEXT N_( \
- "This allows you to select the order in which VLC will choose its " \
- "codecs. For instance, 'a52old,a52,any' will try the old a52 codec " \
- "before the new one. Please be aware that VLC does not make any " \
- "difference between audio or video codecs, so you should always specify " \
- "'any' at the end of the list to make sure there is a fallback for the " \
- "types you didn't specify.")
-
+ "This allows you to select a list of codecs that VLC will use in " \
+ "priority. For instance, 'dummy,a52' will try the dummy and a52 codecs " \
+ "before trying the other ones.")
-#define ENCODER_VIDEO_TEXT N_("Choose preferred video encoder list")
-#define ENCODER_VIDEO_LONGTEXT N_( \
- "This allows you to select the order in which VLC will choose its " \
- "codecs. " )
-#define ENCODER_AUDIO_TEXT N_("Choose preferred audio encoder list")
-#define ENCODER_AUDIO_LONGTEXT N_( \
- "This allows you to select the order in which VLC will choose its " \
- "codecs. " )
+#define ENCODER_TEXT N_("Choose preferred encoders list")
+#define ENCODER_LONGTEXT N_( \
+ "This allows you to select a list of encoders that VLC will use in " \
+ "priority")
#define SOUT_CAT_LONGTEXT N_( \
"These options allow you to set default global options for the " \
/* Decoder options */
add_category_hint( N_("Decoders"), CODEC_CAT_LONGTEXT , VLC_TRUE );
add_module( "codec", "decoder", NULL, NULL, CODEC_TEXT, CODEC_LONGTEXT, VLC_TRUE );
+ add_module( "encoder", "encoder", NULL, NULL, ENCODER_TEXT, ENCODER_LONGTEXT, VLC_TRUE );
/* Stream output options */