Commit 537cb483 authored by Laurent Aimar's avatar Laurent Aimar

* ps: clean up and dvd subtitles support.

parent 6cad86e5
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* pes.c: PES packetizer used by the MPEG multiplexers * pes.c: PES packetizer used by the MPEG multiplexers
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: pes.c,v 1.8 2003/07/15 13:12:00 gbazin Exp $ * $Id: pes.c,v 1.9 2003/08/02 01:33:53 fenrir 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>
...@@ -84,7 +84,7 @@ static inline int PESHeader( uint8_t *p_hdr, mtime_t i_pts, mtime_t i_dts, ...@@ -84,7 +84,7 @@ static inline int PESHeader( uint8_t *p_hdr, mtime_t i_pts, mtime_t i_dts,
if( i_stream_id == PES_PRIVATE_STREAM_1 ) if( i_stream_id == PES_PRIVATE_STREAM_1 )
{ {
i_extra = 1; i_extra = 1;
if( ( i_private_id&0xf0 ) == 0x80 ) if( ( i_private_id&0xf8 ) == 0x80 )
{ {
i_extra += 3; i_extra += 3;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* multiplexer module for vlc * multiplexer module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: ps.c,v 1.14 2003/07/15 16:07:33 gbazin Exp $ * $Id: ps.c,v 1.15 2003/08/02 01:33:53 fenrir 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>
...@@ -29,73 +29,71 @@ ...@@ -29,73 +29,71 @@
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h> #include <vlc/input.h>
#include <vlc/sout.h> #include <vlc/sout.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "codecs.h" #include "codecs.h"
#include "bits.h" #include "bits.h"
#include "pes.h" #include "pes.h"
/* TODO:
* - test support of DTS, LPCM
*
*/
/***************************************************************************** /*****************************************************************************
* Exported prototypes * Module descriptor
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
vlc_module_begin();
set_description( _("PS muxer") );
set_capability( "sout mux", 50 );
add_shortcut( "ps" );
add_shortcut( "mpeg1" );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static int Capability(sout_mux_t *, int, void *, void * ); static int Capability(sout_mux_t *, int, void *, void * );
static int AddStream( sout_mux_t *, sout_input_t * ); 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 * );
static void SetWBE ( uint8_t *p, uint16_t v )
{
p[0] = ( v >> 8 )&0xff;
p[1] = v&0xff;
}
static void SetDWBE( uint8_t *p, uint32_t v )
{
SetWBE( p, ( v >> 16 )&0xffff );
SetWBE( p + 2, v & 0xffff );
}
#define ADD_DWBE( p_buff, v ) \
SetDWBE( (p_buff)->p_buffer + i_buffer, (v) ); \
i_buffer +=4;
/***************************************************************************** /*****************************************************************************
* Module descriptor * Local prototypes
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); static int MuxGetStream ( sout_mux_t *, int *, mtime_t * );
set_description( _("PS muxer") );
set_capability( "sout mux", 50 ); static void MuxWritePackHeader ( sout_mux_t *, sout_buffer_t **, mtime_t );
add_shortcut( "ps" ); static void MuxWriteSystemHeader( sout_mux_t *, sout_buffer_t ** );
add_shortcut( "mpeg1" );
set_callbacks( Open, Close ); static void StreamIdInit ( vlc_bool_t *id, int i_range );
vlc_module_end(); static int StreamIdGet ( vlc_bool_t *id, int i_id_min, int i_id_max );
static void StreamIdRelease ( vlc_bool_t *id, int i_id_min, int i_id );
typedef struct ps_stream_s typedef struct ps_stream_s
{ {
int i_ok;
int i_stream_id; int i_stream_id;
} ps_stream_t; } ps_stream_t;
struct sout_mux_sys_t struct sout_mux_sys_t
{ {
int i_stream_id_mpga; /* Which id are unused */
int i_stream_id_mpgv; vlc_bool_t stream_id_mpga[16]; /* 0xc0 -> 0xcf */
int i_stream_id_a52; vlc_bool_t stream_id_mpgv[16]; /* 0xe0 -> 0xef */
vlc_bool_t stream_id_a52[8]; /* 0x80 -> 0x87 <- FIXME I'm not sure */
vlc_bool_t stream_id_spu[32]; /* 0x20 -> 0x3f */
vlc_bool_t stream_id_dts[8]; /* 0x88 -> 0x8f */
vlc_bool_t stream_id_lpcm[16]; /* 0xa0 -> 0xaf */
int i_audio_bound; int i_audio_bound;
int i_video_bound; int i_video_bound;
...@@ -107,6 +105,7 @@ struct sout_mux_sys_t ...@@ -107,6 +105,7 @@ struct sout_mux_sys_t
vlc_bool_t b_mpeg2; vlc_bool_t b_mpeg2;
}; };
/***************************************************************************** /*****************************************************************************
* Open: * Open:
*****************************************************************************/ *****************************************************************************/
...@@ -117,22 +116,25 @@ static int Open( vlc_object_t *p_this ) ...@@ -117,22 +116,25 @@ static int Open( vlc_object_t *p_this )
msg_Info( p_mux, "Open" ); msg_Info( p_mux, "Open" );
p_sys = malloc( sizeof( sout_mux_sys_t ) );
p_mux->pf_capacity = Capability; p_mux->pf_capacity = Capability;
p_mux->pf_addstream = AddStream; p_mux->pf_addstream = AddStream;
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;
p_mux->i_preheader = 30; // really enough for a pes header p_mux->i_preheader = 30; // really enough for a pes header
p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) );
p_sys->i_stream_id_mpga = 0xc0;
p_sys->i_stream_id_a52 = 0x80; /* Init free stream id */
p_sys->i_stream_id_mpgv = 0xe0; StreamIdInit( p_sys->stream_id_a52, 8 );
p_sys->i_audio_bound = 0; StreamIdInit( p_sys->stream_id_dts, 8 );
p_sys->i_video_bound = 0; StreamIdInit( p_sys->stream_id_mpga, 16 );
StreamIdInit( p_sys->stream_id_mpgv, 16 );
StreamIdInit( p_sys->stream_id_lpcm, 16 );
StreamIdInit( p_sys->stream_id_spu, 32 );
p_sys->i_audio_bound = 0;
p_sys->i_video_bound = 0;
p_sys->i_system_header = 0; p_sys->i_system_header = 0;
p_sys->i_pes_count = 0; p_sys->i_pes_count = 0;
p_sys->b_mpeg2 = !(p_mux->psz_mux && !strcmp( p_mux->psz_mux, "mpeg1" )); p_sys->b_mpeg2 = !(p_mux->psz_mux && !strcmp( p_mux->psz_mux, "mpeg1" ));
...@@ -142,7 +144,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -142,7 +144,6 @@ static int Open( vlc_object_t *p_this )
/***************************************************************************** /*****************************************************************************
* Close: * Close:
*****************************************************************************/ *****************************************************************************/
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;
...@@ -153,13 +154,19 @@ static void Close( vlc_object_t * p_this ) ...@@ -153,13 +154,19 @@ static void Close( vlc_object_t * p_this )
msg_Info( p_mux, "Close" ); msg_Info( p_mux, "Close" );
p_end = sout_BufferNew( p_mux->p_sout, 4 ); p_end = sout_BufferNew( p_mux->p_sout, 4 );
SetDWBE( p_end->p_buffer, 0x01b9 ); p_end->p_buffer[0] = 0x00;
p_end->p_buffer[1] = 0x00;
p_end->p_buffer[2] = 0x01;
p_end->p_buffer[3] = 0xb9;
sout_AccessOutWrite( p_mux->p_access, p_end ); sout_AccessOutWrite( p_mux->p_access, p_end );
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* Capability:
*****************************************************************************/
static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, static int Capability( sout_mux_t *p_mux, int i_query, void *p_args,
void *p_answer ) void *p_answer )
{ {
...@@ -173,72 +180,208 @@ static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, ...@@ -173,72 +180,208 @@ static int Capability( sout_mux_t *p_mux, int i_query, void *p_args,
} }
} }
/*****************************************************************************
* AddStream:
*****************************************************************************/
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 )
{ {
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
ps_stream_t *p_stream; ps_stream_t *p_stream;
msg_Dbg( p_mux, "adding input" ); msg_Dbg( p_mux, "adding input codec=%4.4s", (char*)&p_input->p_fmt->i_fourcc );
p_input->p_sys = (void*)p_stream = malloc( sizeof( ps_stream_t ) ); p_input->p_sys = (void*)p_stream = malloc( sizeof( ps_stream_t ) );
p_stream->i_ok = 0;
switch( p_input->p_fmt->i_cat ) /* Init this new stream */
switch( p_input->p_fmt->i_fourcc )
{ {
case VIDEO_ES: case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
switch( p_input->p_fmt->i_fourcc ) p_stream->i_stream_id = StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
{
case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
p_sys->i_stream_id_mpgv++;
p_sys->i_video_bound++;
break;
default:
return( -1 );
}
break; break;
case VLC_FOURCC( 'l', 'p', 'c', 'm' ):
case AUDIO_ES: p_stream->i_stream_id = 0xbd00|StreamIdGet( p_sys->stream_id_lpcm, 0xa0, 0xaf );
switch( p_input->p_fmt->i_fourcc ) break;
{ case VLC_FOURCC( 'd', 't', 's', ' ' ):
case VLC_FOURCC( 'a', '5', '2', ' ' ): p_stream->i_stream_id = 0xbd00|StreamIdGet( p_sys->stream_id_dts, 0x88, 0x8f );
case VLC_FOURCC( 'a', '5', '2', 'b' ): break;
p_stream->i_stream_id = p_sys->i_stream_id_a52 | case VLC_FOURCC( 'a', '5', '2', ' ' ):
( 0xbd << 8 ); p_stream->i_stream_id = 0xbd00|StreamIdGet( p_sys->stream_id_a52, 0x80, 0x87 );
p_sys->i_stream_id_a52++; break;
p_sys->i_audio_bound++; case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
break; p_stream->i_stream_id = StreamIdGet( p_sys->stream_id_mpga, 0xc0, 0xcf );
case VLC_FOURCC( 'm', 'p', 'g', 'a' ): break;
p_stream->i_stream_id = p_sys->i_stream_id_mpga; case VLC_FOURCC( 's', 'p', 'u', ' ' ):
p_sys->i_stream_id_mpga++; p_stream->i_stream_id = 0xbd00|StreamIdGet( p_sys->stream_id_spu, 0x20, 0x3f );
p_sys->i_audio_bound++;
break;
default:
return( -1 );
}
break; break;
default: default:
return( -1 ); goto error;
}
if( p_stream->i_stream_id < 0 )
{
goto error;
} }
p_stream->i_ok = 1; if( p_input->p_fmt->i_cat == AUDIO_ES )
msg_Dbg( p_mux, "adding input stream_id:0x%x [OK]", {
p_stream->i_stream_id ); p_sys->i_audio_bound++;
}
else if( p_input->p_fmt->i_cat == VIDEO_ES )
{
p_sys->i_video_bound++;
}
return( 0 ); return VLC_SUCCESS;
error:
free( p_stream );
return VLC_EGENERIC;
} }
/*****************************************************************************
* DelStream:
*****************************************************************************/
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 )
{ {
sout_mux_sys_t *p_sys = p_mux->p_sys;
ps_stream_t *p_stream =(ps_stream_t*)p_input->p_sys; ps_stream_t *p_stream =(ps_stream_t*)p_input->p_sys;
msg_Dbg( p_mux, "removing input" ); msg_Dbg( p_mux, "removing input" );
if( p_stream ) switch( p_input->p_fmt->i_fourcc )
{ {
free( p_stream ); case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
StreamIdRelease( p_sys->stream_id_mpgv, 0xe0, p_stream->i_stream_id);
break;
case VLC_FOURCC( 'l', 'p', 'c', 'm' ):
StreamIdRelease( p_sys->stream_id_lpcm, 0xa0, p_stream->i_stream_id&0xff );
break;
case VLC_FOURCC( 'd', 't', 's', ' ' ):
StreamIdRelease( p_sys->stream_id_dts, 0x88, p_stream->i_stream_id&0xff );
break;
case VLC_FOURCC( 'a', '5', '2', ' ' ):
StreamIdRelease( p_sys->stream_id_a52, 0x80, p_stream->i_stream_id&0xff );
break;
case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
StreamIdRelease( p_sys->stream_id_mpga, 0xc0, p_stream->i_stream_id );
break;
case VLC_FOURCC( 's', 'p', 'u', ' ' ):
StreamIdRelease( p_sys->stream_id_spu, 0x20, p_stream->i_stream_id&0xff );
break;
default:
/* Never reached */
break;
} }
return( VLC_SUCCESS );
if( p_input->p_fmt->i_cat == AUDIO_ES )
{
p_sys->i_audio_bound--;
}
else if( p_input->p_fmt->i_cat == VIDEO_ES )
{
p_sys->i_video_bound--;
}
free( p_stream );
return VLC_SUCCESS;
} }
static int MuxWritePackHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf, /*****************************************************************************
* Mux: Call each time there is new data for at least one stream
*****************************************************************************/
static int Mux( sout_mux_t *p_mux )
{
sout_mux_sys_t *p_sys = p_mux->p_sys;
for( ;; )
{
sout_input_t *p_input;
ps_stream_t *p_stream;
sout_buffer_t *p_ps, *p_data;
mtime_t i_dts;
int i_stream;
/* Choose which stream to mux */
if( MuxGetStream( p_mux, &i_stream, &i_dts ) )
{
return VLC_SUCCESS;
}
p_input = p_mux->pp_inputs[i_stream];
p_stream = (ps_stream_t*)p_input->p_sys;
p_ps = NULL;
/* Write regulary PackHeader */
if( p_sys->i_pes_count % 30 == 0)
{
MuxWritePackHeader( p_mux, &p_ps, i_dts );
}
/* Write regulary SystemHeader */
if( p_sys->i_pes_count % 300 == 0 )
{
sout_buffer_t *p_pk;
MuxWriteSystemHeader( p_mux, &p_ps );
/* For MPEG1 streaming, set HEADER flag */
for( p_pk = p_ps; p_pk != NULL; p_pk = p_pk->p_next )
{
p_pk->i_flags |= SOUT_BUFFER_FLAGS_HEADER;
}
}
/* Get and mux a packet */
p_data = sout_FifoGet( p_input->p_fifo );
E_( EStoPES )( p_mux->p_sout,
&p_data, p_data,
p_stream->i_stream_id,
p_mux->p_sys->b_mpeg2 );
sout_BufferChain( &p_ps, p_data );
sout_AccessOutWrite( p_mux->p_access, p_ps );
/* Increase counter */
p_sys->i_pes_count++;
}
return VLC_SUCCESS;
}
/*****************************************************************************
*
*****************************************************************************/
static void StreamIdInit ( vlc_bool_t *id, int i_range )
{
int i;
for( i = 0; i < i_range; i++ )
{
id[i] = VLC_TRUE;
}
}
static int StreamIdGet ( vlc_bool_t *id, int i_id_min, int i_id_max )
{
int i;
for( i = 0; i <= i_id_max - i_id_min; i++ )
{
if( id[i] )
{
id[i] = VLC_FALSE;
return i_id_min + i;
}
}
return -1;
}
static void StreamIdRelease( vlc_bool_t *id, int i_id_min, int i_id )
{
id[i_id - i_id_min] = VLC_TRUE;
}
static void MuxWritePackHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf,
mtime_t i_dts ) mtime_t i_dts )
{ {
sout_buffer_t *p_hdr; sout_buffer_t *p_hdr;
...@@ -252,9 +395,13 @@ static int MuxWritePackHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf, ...@@ -252,9 +395,13 @@ static int MuxWritePackHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf,
bits_write( &bits, 32, 0x01ba ); bits_write( &bits, 32, 0x01ba );
if( p_mux->p_sys->b_mpeg2 ) if( p_mux->p_sys->b_mpeg2 )
{
bits_write( &bits, 2, 0x01 ); bits_write( &bits, 2, 0x01 );
}
else else
{
bits_write( &bits, 4, 0x02 ); bits_write( &bits, 4, 0x02 );
}
bits_write( &bits, 3, ( i_src >> 30 )&0x07 ); bits_write( &bits, 3, ( i_src >> 30 )&0x07 );
bits_write( &bits, 1, 1 ); bits_write( &bits, 1, 1 );
...@@ -279,28 +426,41 @@ static int MuxWritePackHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf, ...@@ -279,28 +426,41 @@ static int MuxWritePackHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf,
bits_write( &bits, 3, 0 ); // stuffing bytes bits_write( &bits, 3, 0 ); // stuffing bytes
} }
if( p_mux->p_sys->b_mpeg2 ) p_hdr->i_size = p_mux->p_sys->b_mpeg2 ? 14: 12;
p_hdr->i_size = 14;
else
p_hdr->i_size = 12;
sout_BufferChain( p_buf, p_hdr ); sout_BufferChain( p_buf, p_hdr );
return( 0 );
} }
static int MuxWriteSystemHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf ) static void MuxWriteSystemHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf )
{ {
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_hdr; sout_buffer_t *p_hdr;
bits_buffer_t bits; bits_buffer_t bits;
vlc_bool_t b_private;
int i_nb_private, i_nb_stream;
int i; int i;
p_hdr = sout_BufferNew( p_mux->p_sout, 12 + p_mux->i_nb_inputs * 3 ); /* Count the number of private stream */
for( i = 0, i_nb_private = 0; i < p_mux->i_nb_inputs; i++ )
{
ps_stream_t *p_stream;
p_stream = (ps_stream_t*)p_mux->pp_inputs[i]->p_sys;
bits_initwrite( &bits, 12 + p_mux->i_nb_inputs * 3, p_hdr->p_buffer ); if( ( p_stream->i_stream_id&0xff00 ) == 0xbd00 )
{
i_nb_private++;
}
}
/* Private stream are declared only one time */
i_nb_stream = p_mux->i_nb_inputs - ( i_nb_private > 0 ? i_nb_private - 1 : 0 );
p_hdr = sout_BufferNew( p_mux->p_sout, 12 + i_nb_stream * 3 );
bits_initwrite( &bits, 12 + i_nb_stream * 3, p_hdr->p_buffer );
bits_write( &bits, 32, 0x01bb ); bits_write( &bits, 32, 0x01bb );
bits_write( &bits, 16, 12 - 6 + p_mux->i_nb_inputs * 3 ); bits_write( &bits, 16, 12 - 6 + i_nb_stream * 3 );
bits_write( &bits, 1, 1 ); bits_write( &bits, 1, 1 );
bits_write( &bits, 22, 0 ); // FIXME rate bound bits_write( &bits, 22, 0 ); // FIXME rate bound
bits_write( &bits, 1, 1 ); bits_write( &bits, 1, 1 );
...@@ -318,36 +478,56 @@ static int MuxWriteSystemHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf ) ...@@ -318,36 +478,56 @@ static int MuxWriteSystemHeader( sout_mux_t *p_mux, sout_buffer_t **p_buf )
bits_write( &bits, 7, 0xff ); // reserved bits bits_write( &bits, 7, 0xff ); // reserved bits
/* stream_id table */ /* stream_id table */
for( i = 0; i < p_mux->i_nb_inputs; i++ ) for( i = 0, b_private = VLC_FALSE; i < p_mux->i_nb_inputs; i++ )
{ {
ps_stream_t *p_stream = (ps_stream_t *)p_mux->pp_inputs[i]->p_sys; sout_input_t *p_input;
ps_stream_t *p_stream;
p_input = p_mux->pp_inputs[i];
p_stream = (ps_stream_t *)p_input->p_sys;
if( p_stream->i_stream_id < 0xc0 ) if( ( p_stream->i_stream_id&0xff00 ) == 0xbd00 )
{ {
/* FIXME */ if( b_private )
{
continue;
}
b_private = VLC_TRUE;
/* Write stream id */
bits_write( &bits, 8, 0xbd );
}
else
{
/* Write stream id */
bits_write( &bits, 8, p_stream->i_stream_id&0xff );
} }
bits_write( &bits, 8, p_stream->i_stream_id ); // stream ID
bits_write( &bits, 2, 0x03 ); bits_write( &bits, 2, 0x03 );
if( p_stream->i_stream_id < 0xe0 ) /* FIXME */ if( p_input->p_fmt->i_cat == AUDIO_ES )
{ {
/* audio */
bits_write( &bits, 1, 0 ); bits_write( &bits, 1, 0 );
bits_write( &bits, 13, /* stream->max_buffer_size */ 0 / 128 ); bits_write( &bits, 13, /* stream->max_buffer_size */ 0 / 128 );
} else { }
/* video */ else if( p_input->p_fmt->i_cat == VIDEO_ES )
{
bits_write( &bits, 1, 1 ); bits_write( &bits, 1, 1 );
bits_write( &bits, 13, /* stream->max_buffer_size */ 0 / 1024 ); bits_write( &bits, 13, /* stream->max_buffer_size */ 0 / 1024);
}
else
{
/* FIXME */
bits_write( &bits, 1, 0 );
bits_write( &bits, 13, /* stream->max_buffer_size */ 0 );
} }
} }
sout_BufferChain( p_buf, p_hdr ); sout_BufferChain( p_buf, p_hdr );
return( 0 );
} }
/* return stream number to be muxed */ /*
static int MuxGetStream( sout_mux_t *p_mux, * Find stream to be muxed.
int *pi_stream, */
static int MuxGetStream( sout_mux_t *p_mux,
int *pi_stream,
mtime_t *pi_dts ) mtime_t *pi_dts )
{ {
mtime_t i_dts; mtime_t i_dts;
...@@ -356,88 +536,33 @@ static int MuxGetStream( sout_mux_t *p_mux, ...@@ -356,88 +536,33 @@ static int MuxGetStream( sout_mux_t *p_mux,
for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ ) for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
{ {
sout_fifo_t *p_fifo; sout_input_t *p_input = p_mux->pp_inputs[i];
sout_buffer_t *p_data;
p_fifo = p_mux->pp_inputs[i]->p_fifo;
if( p_fifo->i_depth > 1 ) if( p_input->p_fifo->i_depth <= 0 )
{ {
sout_buffer_t *p_buf; if( p_input->p_fmt->i_cat == AUDIO_ES ||
p_input->p_fmt->i_cat == VIDEO_ES )
p_buf = sout_FifoShow( p_fifo );
if( i_stream < 0 || p_buf->i_dts < i_dts )
{ {
i_dts = p_buf->i_dts; /* We need that audio+video fifo contain at least 1 packet */
i_stream = i; return VLC_EGENERIC;
} }
/* SPU */
continue;
} }
else
p_data = sout_FifoShow( p_input->p_fifo );
if( i_stream == -1 ||
p_data->i_dts < i_dts )
{ {
return( -1 ); // wait that all fifo have at least 2 packets i_stream = i;
i_dts = p_data->i_dts;
} }
} }
if( pi_stream ) *pi_stream = i_stream;
{ *pi_dts = i_dts;
*pi_stream = i_stream;
}
if( pi_dts )
{
*pi_dts = i_dts;
}
return( i_stream ); return VLC_SUCCESS;
} }
static int Mux( sout_mux_t *p_mux )
{
sout_mux_sys_t *p_sys = p_mux->p_sys;
mtime_t i_dts;
int i_stream;
for( ;; )
{
sout_input_t *p_input;
ps_stream_t *p_stream;
sout_fifo_t *p_fifo;
sout_buffer_t *p_hdr = NULL, *p_data;
if( MuxGetStream( p_mux, &i_stream, &i_dts ) < 0 )
{
return( VLC_SUCCESS );
}
p_input = p_mux->pp_inputs[i_stream];
p_fifo = p_input->p_fifo;
p_stream = (ps_stream_t*)p_input->p_sys;
if( p_sys->i_pes_count % 30 == 0)
{
MuxWritePackHeader( p_mux, &p_hdr, i_dts );
}
if( p_sys->i_pes_count % 300 == 0 )
{
sout_buffer_t *p_buf;
MuxWriteSystemHeader( p_mux, &p_hdr );
/* For MPEG1 streaming, set HEADER flag */
for( p_buf = p_hdr; p_buf != NULL; p_buf = p_buf->p_next )
{
p_buf->i_flags |= SOUT_BUFFER_FLAGS_HEADER;
}
}
p_data = sout_FifoGet( p_fifo );
E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id,
p_mux->p_sys->b_mpeg2 );
sout_BufferChain( &p_hdr, p_data );
sout_AccessOutWrite( p_mux->p_access, p_hdr );
p_sys->i_pes_count++;
}
return( 0 );
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment