mirror of https://code.videolan.org/videolan/vlc
* modules/codec/flac.c: added a FLAC encoder.
* modules/mux/dummy.c, modules/mux/ogg.c: you can output "normal" flac streams with the es/dummy muxer or output them with an Ogg container.
This commit is contained in:
parent
ea1b641e16
commit
09d997200c
|
@ -1,8 +1,8 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* flac.c: flac decoder/packetizer module making use of libflac
|
* flac.c: flac decoder/packetizer/encoder module making use of libflac
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1999-2001 VideoLAN
|
* Copyright (C) 1999-2001 VideoLAN
|
||||||
* $Id: flac.c,v 1.2 2003/11/21 12:18:54 gbazin Exp $
|
* $Id: flac.c,v 1.3 2003/11/21 20:49:13 gbazin Exp $
|
||||||
*
|
*
|
||||||
* Authors: Gildas Bazin <gbazin@netcourrier.com>
|
* Authors: Gildas Bazin <gbazin@netcourrier.com>
|
||||||
* Sigmund Augdal <sigmunau@idi.ntnu.no>
|
* Sigmund Augdal <sigmunau@idi.ntnu.no>
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
#include <vlc/input.h>
|
#include <vlc/input.h>
|
||||||
|
|
||||||
#include <FLAC/stream_decoder.h>
|
#include <FLAC/stream_decoder.h>
|
||||||
|
#include <FLAC/stream_encoder.h>
|
||||||
|
|
||||||
#include "vlc_block_helper.h"
|
#include "vlc_block_helper.h"
|
||||||
|
|
||||||
|
@ -103,6 +104,9 @@ static int OpenDecoder ( vlc_object_t * );
|
||||||
static int OpenPacketizer( vlc_object_t * );
|
static int OpenPacketizer( vlc_object_t * );
|
||||||
static void CloseDecoder ( vlc_object_t * );
|
static void CloseDecoder ( vlc_object_t * );
|
||||||
|
|
||||||
|
static int OpenEncoder ( vlc_object_t * );
|
||||||
|
static void CloseEncoder ( vlc_object_t * );
|
||||||
|
|
||||||
static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
|
static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
|
||||||
static block_t *PacketizeBlock( decoder_t *, block_t ** );
|
static block_t *PacketizeBlock( decoder_t *, block_t ** );
|
||||||
|
|
||||||
|
@ -150,6 +154,11 @@ vlc_module_begin();
|
||||||
set_capability( "packetizer", 100 );
|
set_capability( "packetizer", 100 );
|
||||||
set_callbacks( OpenPacketizer, CloseDecoder );
|
set_callbacks( OpenPacketizer, CloseDecoder );
|
||||||
|
|
||||||
|
add_submodule();
|
||||||
|
set_description( _("Flac audio encoder") );
|
||||||
|
set_capability( "encoder", 100 );
|
||||||
|
set_callbacks( OpenEncoder, CloseEncoder );
|
||||||
|
|
||||||
vlc_module_end();
|
vlc_module_end();
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -211,10 +220,9 @@ static int OpenDecoder( vlc_object_t *p_this )
|
||||||
|
|
||||||
/* Decode STREAMINFO */
|
/* Decode STREAMINFO */
|
||||||
msg_Dbg( p_dec, "decode STREAMINFO" );
|
msg_Dbg( p_dec, "decode STREAMINFO" );
|
||||||
p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra + 4 );
|
p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra );
|
||||||
memcpy( p_sys->p_block->p_buffer + 4, p_dec->fmt_in.p_extra,
|
memcpy( p_sys->p_block->p_buffer, p_dec->fmt_in.p_extra,
|
||||||
p_dec->fmt_in.i_extra );
|
p_dec->fmt_in.i_extra );
|
||||||
memcpy( p_sys->p_block->p_buffer, "fLaC", 4 );
|
|
||||||
FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
|
FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
|
||||||
msg_Dbg( p_dec, "STREAMINFO decoded" );
|
msg_Dbg( p_dec, "STREAMINFO decoded" );
|
||||||
|
|
||||||
|
@ -230,7 +238,7 @@ static int OpenPacketizer( vlc_object_t *p_this )
|
||||||
if( i_ret == VLC_SUCCESS )
|
if( i_ret == VLC_SUCCESS )
|
||||||
{
|
{
|
||||||
p_dec->p_sys->b_packetizer = VLC_TRUE;
|
p_dec->p_sys->b_packetizer = VLC_TRUE;
|
||||||
p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','a','c');
|
es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
|
||||||
}
|
}
|
||||||
|
|
||||||
return i_ret;
|
return i_ret;
|
||||||
|
@ -1009,3 +1017,205 @@ static uint8_t flac_crc8( const uint8_t *data, unsigned len )
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* encoder_sys_t : flac encoder descriptor
|
||||||
|
*****************************************************************************/
|
||||||
|
struct encoder_sys_t
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Input properties
|
||||||
|
*/
|
||||||
|
int i_headers;
|
||||||
|
|
||||||
|
int i_samples_delay;
|
||||||
|
int i_channels;
|
||||||
|
|
||||||
|
FLAC__int32 *p_buffer;
|
||||||
|
int i_buffer;
|
||||||
|
|
||||||
|
block_t *p_chain;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FLAC properties
|
||||||
|
*/
|
||||||
|
FLAC__StreamEncoder *p_flac;
|
||||||
|
FLAC__StreamMetadata_StreamInfo stream_info;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common properties
|
||||||
|
*/
|
||||||
|
mtime_t i_pts;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STREAMINFO_SIZE 38
|
||||||
|
|
||||||
|
static block_t *Encode( encoder_t *, aout_buffer_t * );
|
||||||
|
|
||||||
|
static FLAC__StreamEncoderWriteStatus
|
||||||
|
EncoderWriteCallback( const FLAC__StreamEncoder *encoder,
|
||||||
|
const FLAC__byte buffer[],
|
||||||
|
unsigned bytes, unsigned samples,
|
||||||
|
unsigned current_frame, void *client_data );
|
||||||
|
|
||||||
|
static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder,
|
||||||
|
const FLAC__StreamMetadata *metadata,
|
||||||
|
void *client_data );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* OpenEncoder: probe the encoder and return score
|
||||||
|
*****************************************************************************/
|
||||||
|
static int OpenEncoder( vlc_object_t *p_this )
|
||||||
|
{
|
||||||
|
encoder_t *p_enc = (encoder_t *)p_this;
|
||||||
|
encoder_sys_t *p_sys;
|
||||||
|
|
||||||
|
if( p_enc->fmt_out.i_codec != VLC_FOURCC('f','l','a','c') )
|
||||||
|
{
|
||||||
|
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_enc->pf_encode_audio = Encode;
|
||||||
|
p_sys->i_headers = 0;
|
||||||
|
p_sys->p_buffer = 0;
|
||||||
|
p_sys->i_buffer = 0;
|
||||||
|
|
||||||
|
/* Create flac encoder */
|
||||||
|
p_sys->p_flac = FLAC__stream_encoder_new();
|
||||||
|
|
||||||
|
FLAC__stream_encoder_set_streamable_subset( p_sys->p_flac, 1 );
|
||||||
|
FLAC__stream_encoder_set_channels( p_sys->p_flac,
|
||||||
|
p_enc->fmt_in.audio.i_channels );
|
||||||
|
FLAC__stream_encoder_set_sample_rate( p_sys->p_flac,
|
||||||
|
p_enc->fmt_in.audio.i_rate );
|
||||||
|
FLAC__stream_encoder_set_bits_per_sample( p_sys->p_flac, 16 );
|
||||||
|
p_enc->fmt_in.i_codec = AOUT_FMT_S16_NE;
|
||||||
|
|
||||||
|
FLAC__stream_encoder_set_write_callback( p_sys->p_flac,
|
||||||
|
EncoderWriteCallback );
|
||||||
|
FLAC__stream_encoder_set_metadata_callback( p_sys->p_flac,
|
||||||
|
EncoderMetadataCallback );
|
||||||
|
FLAC__stream_encoder_set_client_data( p_sys->p_flac, p_enc );
|
||||||
|
|
||||||
|
/* Get and store the STREAMINFO metadata block as a p_extra */
|
||||||
|
p_sys->p_chain = 0;
|
||||||
|
FLAC__stream_encoder_init( p_sys->p_flac );
|
||||||
|
|
||||||
|
return VLC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Encode: the whole thing
|
||||||
|
****************************************************************************
|
||||||
|
* This function spits out ogg packets.
|
||||||
|
****************************************************************************/
|
||||||
|
static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
|
||||||
|
{
|
||||||
|
encoder_sys_t *p_sys = p_enc->p_sys;
|
||||||
|
block_t *p_chain;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
p_sys->i_pts = p_aout_buf->start_date -
|
||||||
|
(mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
|
||||||
|
(mtime_t)p_enc->fmt_in.audio.i_rate;
|
||||||
|
|
||||||
|
p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
|
||||||
|
|
||||||
|
/* Convert samples to FLAC__int32 */
|
||||||
|
if( p_sys->i_buffer < p_aout_buf->i_nb_bytes * 2 )
|
||||||
|
{
|
||||||
|
p_sys->p_buffer =
|
||||||
|
realloc( p_sys->p_buffer, p_aout_buf->i_nb_bytes * 2 );
|
||||||
|
p_sys->i_buffer = p_aout_buf->i_nb_bytes * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0 ; i < p_aout_buf->i_nb_bytes / 2 ; i++ )
|
||||||
|
{
|
||||||
|
p_sys->p_buffer[i]= ((int16_t *)p_aout_buf->p_buffer)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
FLAC__stream_encoder_process_interleaved( p_sys->p_flac, p_sys->p_buffer,
|
||||||
|
p_aout_buf->i_nb_samples );
|
||||||
|
|
||||||
|
p_chain = p_sys->p_chain;
|
||||||
|
p_sys->p_chain = 0;
|
||||||
|
|
||||||
|
return p_chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* CloseEncoder: encoder destruction
|
||||||
|
*****************************************************************************/
|
||||||
|
static void CloseEncoder( vlc_object_t *p_this )
|
||||||
|
{
|
||||||
|
encoder_t *p_enc = (encoder_t *)p_this;
|
||||||
|
encoder_sys_t *p_sys = p_enc->p_sys;
|
||||||
|
|
||||||
|
FLAC__stream_encoder_delete( p_sys->p_flac );
|
||||||
|
|
||||||
|
if( p_sys->p_buffer ) free( p_sys->p_buffer );
|
||||||
|
free( p_sys );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* EncoderMetadataCallback: called by libflac to output metadata
|
||||||
|
*****************************************************************************/
|
||||||
|
static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder,
|
||||||
|
const FLAC__StreamMetadata *metadata,
|
||||||
|
void *client_data )
|
||||||
|
{
|
||||||
|
encoder_t *p_enc = (encoder_t *)client_data;
|
||||||
|
|
||||||
|
msg_Err( p_enc, "MetadataCallback: %i", metadata->type );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* EncoderWriteCallback: called by libflac to output encoded samples
|
||||||
|
*****************************************************************************/
|
||||||
|
static FLAC__StreamEncoderWriteStatus
|
||||||
|
EncoderWriteCallback( const FLAC__StreamEncoder *encoder,
|
||||||
|
const FLAC__byte buffer[],
|
||||||
|
unsigned bytes, unsigned samples,
|
||||||
|
unsigned current_frame, void *client_data )
|
||||||
|
{
|
||||||
|
encoder_t *p_enc = (encoder_t *)client_data;
|
||||||
|
encoder_sys_t *p_sys = p_enc->p_sys;
|
||||||
|
block_t *p_block;
|
||||||
|
|
||||||
|
if( samples == 0 && p_sys->i_headers <= 1 )
|
||||||
|
{
|
||||||
|
if( p_sys->i_headers == 1 )
|
||||||
|
{
|
||||||
|
msg_Err( p_enc, "Writing STREAMINFO: %i", bytes );
|
||||||
|
|
||||||
|
/* Backup the STREAMINFO metadata block */
|
||||||
|
p_enc->fmt_out.i_extra = STREAMINFO_SIZE + 4;
|
||||||
|
p_enc->fmt_out.p_extra = malloc( STREAMINFO_SIZE + 4 );
|
||||||
|
memcpy( p_enc->fmt_out.p_extra, "fLaC", 4 );
|
||||||
|
memcpy( ((uint8_t *)p_enc->fmt_out.p_extra) + 4, buffer,
|
||||||
|
STREAMINFO_SIZE + 4 );
|
||||||
|
|
||||||
|
/* Fake this as the last metadata block */
|
||||||
|
((uint8_t*)p_enc->fmt_out.p_extra)[4] |= 0x80;
|
||||||
|
}
|
||||||
|
p_sys->i_headers++;
|
||||||
|
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_block = block_New( p_enc, bytes );
|
||||||
|
memcpy( p_block->p_buffer, buffer, bytes );
|
||||||
|
|
||||||
|
p_block->i_dts = p_block->i_pts = p_block->i_length = 0;
|
||||||
|
|
||||||
|
block_ChainAppend( &p_sys->p_chain, p_block );
|
||||||
|
|
||||||
|
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* flac.c : FLAC demux module for vlc
|
* flac.c : FLAC demux module for vlc
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 2001 VideoLAN
|
* Copyright (C) 2001 VideoLAN
|
||||||
* $Id: flac.c,v 1.7 2003/11/21 12:18:54 gbazin Exp $
|
* $Id: flac.c,v 1.8 2003/11/21 20:49:13 gbazin Exp $
|
||||||
*
|
*
|
||||||
* Authors: Gildas Bazin <gbazin@netcourrier.com>
|
* Authors: Gildas Bazin <gbazin@netcourrier.com>
|
||||||
*
|
*
|
||||||
|
@ -99,18 +99,15 @@ static int Open( vlc_object_t * p_this )
|
||||||
es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'f', 'l', 'a', 'c' ) );
|
es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'f', 'l', 'a', 'c' ) );
|
||||||
p_sys->b_start = VLC_TRUE;
|
p_sys->b_start = VLC_TRUE;
|
||||||
|
|
||||||
/* Skip stream marker */
|
|
||||||
stream_Read( p_input->s, NULL, 4 );
|
|
||||||
|
|
||||||
/* We need to read and store the STREAMINFO metadata */
|
/* We need to read and store the STREAMINFO metadata */
|
||||||
i_peek = stream_Peek( p_input->s, &p_peek, 4 );
|
i_peek = stream_Peek( p_input->s, &p_peek, 8 );
|
||||||
if( p_peek[0] & 0x7F )
|
if( p_peek[4] & 0x7F )
|
||||||
{
|
{
|
||||||
msg_Err( p_input, "This isn't a STREAMINFO metadata block" );
|
msg_Err( p_input, "This isn't a STREAMINFO metadata block" );
|
||||||
return VLC_EGENERIC;
|
return VLC_EGENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ((p_peek[1]<<16)+(p_peek[2]<<8)+p_peek[3]) != (STREAMINFO_SIZE - 4) )
|
if( ((p_peek[5]<<16)+(p_peek[6]<<8)+p_peek[7]) != (STREAMINFO_SIZE - 4) )
|
||||||
{
|
{
|
||||||
msg_Err( p_input, "Invalid size for a STREAMINFO metadata block" );
|
msg_Err( p_input, "Invalid size for a STREAMINFO metadata block" );
|
||||||
return VLC_EGENERIC;
|
return VLC_EGENERIC;
|
||||||
|
@ -132,15 +129,16 @@ static int Open( vlc_object_t * p_this )
|
||||||
VLC_FOURCC( 'f', 'l', 'a', 'c' ) );
|
VLC_FOURCC( 'f', 'l', 'a', 'c' ) );
|
||||||
|
|
||||||
/* Store STREAMINFO for the decoder and packetizer */
|
/* Store STREAMINFO for the decoder and packetizer */
|
||||||
p_sys->p_packetizer->fmt_in.i_extra = fmt.i_extra = STREAMINFO_SIZE;
|
p_sys->p_packetizer->fmt_in.i_extra = fmt.i_extra = STREAMINFO_SIZE + 4;
|
||||||
p_sys->p_packetizer->fmt_in.p_extra = malloc( STREAMINFO_SIZE );
|
p_sys->p_packetizer->fmt_in.p_extra = malloc( STREAMINFO_SIZE + 4 );
|
||||||
stream_Read( p_input->s, p_sys->p_packetizer->fmt_in.p_extra,
|
stream_Read( p_input->s, p_sys->p_packetizer->fmt_in.p_extra,
|
||||||
STREAMINFO_SIZE );
|
STREAMINFO_SIZE + 4 );
|
||||||
|
|
||||||
/* Fake this as the last metadata block */
|
/* Fake this as the last metadata block */
|
||||||
((uint8_t*)p_sys->p_packetizer->fmt_in.p_extra)[0] |= 0x80;
|
((uint8_t*)p_sys->p_packetizer->fmt_in.p_extra)[4] |= 0x80;
|
||||||
fmt.p_extra = malloc( STREAMINFO_SIZE );
|
fmt.p_extra = malloc( STREAMINFO_SIZE + 4 );
|
||||||
memcpy( fmt.p_extra, p_sys->p_packetizer->fmt_in.p_extra, STREAMINFO_SIZE);
|
memcpy( fmt.p_extra, p_sys->p_packetizer->fmt_in.p_extra,
|
||||||
|
STREAMINFO_SIZE + 4 );
|
||||||
|
|
||||||
p_sys->p_packetizer->p_module =
|
p_sys->p_packetizer->p_module =
|
||||||
module_Need( p_sys->p_packetizer, "packetizer", NULL );
|
module_Need( p_sys->p_packetizer, "packetizer", NULL );
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* dummy.c
|
* dummy.c: dummy muxer module for vlc
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 2001, 2002 VideoLAN
|
* Copyright (C) 2001, 2002 VideoLAN
|
||||||
* $Id: dummy.c,v 1.8 2003/08/17 18:44:26 fenrir Exp $
|
* $Id: dummy.c,v 1.9 2003/11/21 20:49:14 gbazin Exp $
|
||||||
*
|
*
|
||||||
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
|
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
|
||||||
* Eric Petit <titer@videolan.org>
|
* Eric Petit <titer@videolan.org>
|
||||||
|
@ -47,7 +47,6 @@ vlc_module_begin();
|
||||||
set_callbacks( Open, Close );
|
set_callbacks( Open, Close );
|
||||||
vlc_module_end();
|
vlc_module_end();
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Exported prototypes
|
* Exported prototypes
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
@ -56,12 +55,20 @@ static int AddStream( sout_mux_t *, sout_input_t * );
|
||||||
static int DelStream( sout_mux_t *, sout_input_t * );
|
static int DelStream( sout_mux_t *, sout_input_t * );
|
||||||
static int Mux ( sout_mux_t * );
|
static int Mux ( sout_mux_t * );
|
||||||
|
|
||||||
|
struct sout_mux_sys_t
|
||||||
|
{
|
||||||
|
/* Some streams have special initialization data, we'll output this
|
||||||
|
* data as an header in the stream. */
|
||||||
|
vlc_bool_t b_header;
|
||||||
|
};
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open:
|
* Open:
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int Open( vlc_object_t *p_this )
|
static int Open( vlc_object_t *p_this )
|
||||||
{
|
{
|
||||||
sout_mux_t *p_mux = (sout_mux_t*)p_this;
|
sout_mux_t *p_mux = (sout_mux_t*)p_this;
|
||||||
|
sout_mux_sys_t *p_sys;
|
||||||
|
|
||||||
msg_Dbg( p_mux, "Dummy/Raw muxer opened" );
|
msg_Dbg( p_mux, "Dummy/Raw muxer opened" );
|
||||||
msg_Info( p_mux, "Open" );
|
msg_Info( p_mux, "Open" );
|
||||||
|
@ -71,6 +78,9 @@ static int Open( vlc_object_t *p_this )
|
||||||
p_mux->pf_delstream = DelStream;
|
p_mux->pf_delstream = DelStream;
|
||||||
p_mux->pf_mux = Mux;
|
p_mux->pf_mux = Mux;
|
||||||
|
|
||||||
|
p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) );
|
||||||
|
p_sys->b_header = VLC_TRUE;
|
||||||
|
|
||||||
return VLC_SUCCESS;
|
return VLC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +91,10 @@ static int Open( vlc_object_t *p_this )
|
||||||
static void Close( vlc_object_t * p_this )
|
static void Close( vlc_object_t * p_this )
|
||||||
{
|
{
|
||||||
sout_mux_t *p_mux = (sout_mux_t*)p_this;
|
sout_mux_t *p_mux = (sout_mux_t*)p_this;
|
||||||
|
sout_mux_sys_t *p_sys = p_mux->p_sys;
|
||||||
|
|
||||||
msg_Dbg( p_mux, "Dummy/Raw muxer closed" );
|
msg_Dbg( p_mux, "Dummy/Raw muxer closed" );
|
||||||
|
free( p_sys );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Capability( sout_mux_t *p_mux, int i_query,
|
static int Capability( sout_mux_t *p_mux, int i_query,
|
||||||
|
@ -101,24 +113,42 @@ static int Capability( sout_mux_t *p_mux, int i_query,
|
||||||
static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
|
static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
|
||||||
{
|
{
|
||||||
msg_Dbg( p_mux, "adding input" );
|
msg_Dbg( p_mux, "adding input" );
|
||||||
return( 0 );
|
return VLC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
|
static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
|
||||||
{
|
{
|
||||||
|
|
||||||
msg_Dbg( p_mux, "removing input" );
|
msg_Dbg( p_mux, "removing input" );
|
||||||
return( 0 );
|
return VLC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Mux ( sout_mux_t *p_mux )
|
static int Mux( sout_mux_t *p_mux )
|
||||||
{
|
{
|
||||||
|
sout_mux_sys_t *p_sys = p_mux->p_sys;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for( i = 0; i < p_mux->i_nb_inputs; i++ )
|
for( i = 0; i < p_mux->i_nb_inputs; i++ )
|
||||||
{
|
{
|
||||||
int i_count;
|
int i_count;
|
||||||
sout_fifo_t *p_fifo;
|
sout_fifo_t *p_fifo;
|
||||||
|
|
||||||
|
if( p_sys->b_header && p_mux->pp_inputs[i]->p_fmt->i_extra )
|
||||||
|
{
|
||||||
|
/* Write header data */
|
||||||
|
sout_buffer_t *p_data;
|
||||||
|
p_data = sout_BufferNew( p_mux->p_sout,
|
||||||
|
p_mux->pp_inputs[i]->p_fmt->i_extra );
|
||||||
|
|
||||||
|
memcpy( p_data->p_buffer, p_mux->pp_inputs[i]->p_fmt->p_extra,
|
||||||
|
p_mux->pp_inputs[i]->p_fmt->i_extra );
|
||||||
|
|
||||||
|
p_data->i_size = p_mux->pp_inputs[i]->p_fmt->i_extra;
|
||||||
|
p_data->i_dts = p_data->i_pts = p_data->i_length = 0;
|
||||||
|
|
||||||
|
msg_Dbg( p_mux, "writing header data" );
|
||||||
|
sout_AccessOutWrite( p_mux->p_access, p_data );
|
||||||
|
}
|
||||||
|
|
||||||
p_fifo = p_mux->pp_inputs[i]->p_fifo;
|
p_fifo = p_mux->pp_inputs[i]->p_fifo;
|
||||||
i_count = p_fifo->i_depth;
|
i_count = p_fifo->i_depth;
|
||||||
while( i_count > 0 )
|
while( i_count > 0 )
|
||||||
|
@ -133,6 +163,7 @@ static int Mux ( sout_mux_t *p_mux )
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return( 0 );
|
p_sys->b_header = VLC_FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
|
return VLC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* ogg.c: ogg muxer module for vlc
|
* ogg.c: ogg muxer module for vlc
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 2001, 2002 VideoLAN
|
* Copyright (C) 2001, 2002 VideoLAN
|
||||||
* $Id: ogg.c,v 1.21 2003/11/21 15:32:08 fenrir Exp $
|
* $Id: ogg.c,v 1.22 2003/11/21 20:49:14 gbazin Exp $
|
||||||
*
|
*
|
||||||
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
|
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
|
||||||
* Gildas Bazin <gbazin@netcourrier.com>
|
* Gildas Bazin <gbazin@netcourrier.com>
|
||||||
|
@ -426,6 +426,10 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
|
||||||
msg_Dbg( p_mux, "speex stream" );
|
msg_Dbg( p_mux, "speex stream" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VLC_FOURCC( 'f', 'l', 'a', 'c' ):
|
||||||
|
msg_Dbg( p_mux, "flac stream" );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FREE( p_input->p_sys );
|
FREE( p_input->p_sys );
|
||||||
return( VLC_EGENERIC );
|
return( VLC_EGENERIC );
|
||||||
|
@ -638,6 +642,18 @@ static sout_buffer_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )
|
||||||
|
{
|
||||||
|
/* flac stream marker (yeah, only that in the 1st packet) */
|
||||||
|
op.packet = "fLaC";
|
||||||
|
op.bytes = 4;
|
||||||
|
op.b_o_s = 1;
|
||||||
|
op.e_o_s = 0;
|
||||||
|
op.granulepos = 0;
|
||||||
|
op.packetno = p_stream->i_packet_no++;
|
||||||
|
ogg_stream_packetin( &p_stream->os, &op );
|
||||||
|
p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* ds header */
|
/* ds header */
|
||||||
|
@ -689,7 +705,7 @@ static sout_buffer_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts )
|
||||||
sout_BufferChain( &p_hdr, p_og );
|
sout_BufferChain( &p_hdr, p_og );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if( p_stream->i_fourcc != VLC_FOURCC( 'f', 'l', 'a', 'c' ) )
|
||||||
{
|
{
|
||||||
uint8_t com[128];
|
uint8_t com[128];
|
||||||
int i_com;
|
int i_com;
|
||||||
|
@ -708,13 +724,22 @@ static sout_buffer_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts )
|
||||||
sout_BufferChain( &p_hdr, p_og );
|
sout_BufferChain( &p_hdr, p_og );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special case for mp4v */
|
/* Special case for mp4v and flac */
|
||||||
if( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) &&
|
if( ( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) ||
|
||||||
|
p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) ) &&
|
||||||
p_mux->pp_inputs[i]->p_fmt->i_extra )
|
p_mux->pp_inputs[i]->p_fmt->i_extra )
|
||||||
{
|
{
|
||||||
/* Send a packet with the VOL data */
|
/* Send a packet with the VOL data for mp4v
|
||||||
|
* or STREAMINFO for flac */
|
||||||
|
msg_Dbg( p_mux, "writing extra data" );
|
||||||
op.bytes = p_mux->pp_inputs[i]->p_fmt->i_extra;
|
op.bytes = p_mux->pp_inputs[i]->p_fmt->i_extra;
|
||||||
op.packet = p_mux->pp_inputs[i]->p_fmt->p_extra;
|
op.packet = p_mux->pp_inputs[i]->p_fmt->p_extra;
|
||||||
|
if( p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )
|
||||||
|
{
|
||||||
|
/* Skip the flac stream marker */
|
||||||
|
((uint8_t *)op.bytes) -= 4;
|
||||||
|
((uint8_t *)op.packet) += 4;
|
||||||
|
}
|
||||||
op.b_o_s = 0;
|
op.b_o_s = 0;
|
||||||
op.e_o_s = 0;
|
op.e_o_s = 0;
|
||||||
op.granulepos = 0;
|
op.granulepos = 0;
|
||||||
|
|
Loading…
Reference in New Issue