* avi.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: avi.c,v 1.12 2003/04/13 20:00:21 fenrir Exp $
+ * $Id: avi.c,v 1.16 2003/11/21 15:32:08 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
/* TODO: add OpenDML write support */
#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/sout.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
#include "codecs.h"
-
-#define AVIF_HASINDEX 0x00000010 // Index at end of file?
-#define AVIF_MUSTUSEINDEX 0x00000020
-#define AVIF_ISINTERLEAVED 0x00000100
-#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames?
-#define AVIF_WASCAPTUREFILE 0x00010000
-#define AVIF_COPYRIGHTED 0x00020000
-
-/* Flags for index */
-#define AVIIF_LIST 0x00000001L /* chunk is a 'LIST' */
-#define AVIIF_KEYFRAME 0x00000010L /* this frame is a key frame.*/
-#define AVIIF_NOTIME 0x00000100L /* this frame doesn't take any time */
-#define AVIIF_COMPUSE 0x0FFF0000L /* these bits are for compressor use */
-
-/*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
-static int Open ( vlc_object_t * );
-static void Close ( vlc_object_t * );
-
-static int Capability(sout_mux_t *, int , void *, void * );
-static int AddStream( sout_mux_t *, sout_input_t * );
-static int DelStream( sout_mux_t *, sout_input_t * );
-static int Mux ( sout_mux_t * );
-
-static sout_buffer_t *avi_HeaderCreateRIFF( sout_mux_t * );
-static sout_buffer_t *avi_HeaderCreateidx1( sout_mux_t * );
-
-static void SetFCC( uint8_t *p, char *fcc )
-{
- p[0] = fcc[0];
- p[1] = fcc[1];
- p[2] = fcc[2];
- p[3] = fcc[3];
-}
-
-static void SetDWLE( uint8_t *p, uint32_t i_dw )
-{
- p[3] = ( i_dw >> 24 )&0xff;
- p[2] = ( i_dw >> 16 )&0xff;
- p[1] = ( i_dw >> 8 )&0xff;
- p[0] = ( i_dw )&0xff;
-}
-
/*****************************************************************************
* Module descriptor
*****************************************************************************/
+static int Open ( vlc_object_t * );
+static void Close ( vlc_object_t * );
+
vlc_module_begin();
set_description( _("Avi muxer") );
set_capability( "sout mux", 5 );
set_callbacks( Open, Close );
vlc_module_end();
-// FIXME FIXME
-#define HDR_SIZE 10240
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Capability(sout_mux_t *, int , void *, void * );
+static int AddStream( sout_mux_t *, sout_input_t * );
+static int DelStream( sout_mux_t *, sout_input_t * );
+static int Mux ( sout_mux_t * );
typedef struct avi_stream_s
{
char fcc[4];
- //mtime_t i_first_pts;
mtime_t i_duration; // in µs
int i_frames; // total frame count
};
+// FIXME FIXME
+#define HDR_SIZE 10240
+
+/* Flags in avih */
+#define AVIF_HASINDEX 0x00000010 // Index at end of file?
+#define AVIF_ISINTERLEAVED 0x00000100
+#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames?
+
+/* Flags for index */
+#define AVIIF_KEYFRAME 0x00000010L /* this frame is a key frame.*/
+
+
+static sout_buffer_t *avi_HeaderCreateRIFF( sout_mux_t * );
+static sout_buffer_t *avi_HeaderCreateidx1( sout_mux_t * );
+
+static void SetFCC( uint8_t *p, char *fcc )
+{
+ memcpy( p, fcc, 4 );
+}
+
+static void SetDWLE( uint8_t *p, uint32_t i_dw )
+{
+ p[3] = ( i_dw >> 24 )&0xff;
+ p[2] = ( i_dw >> 16 )&0xff;
+ p[1] = ( i_dw >> 8 )&0xff;
+ p[0] = ( i_dw )&0xff;
+}
+
+
/*****************************************************************************
* Open:
*****************************************************************************/
{
sout_mux_t *p_mux = (sout_mux_t*)p_this;
sout_mux_sys_t *p_sys = p_mux->p_sys;
- //sout_buffer_t *p_hdr;
+
+ msg_Dbg( p_mux, "AVI muxer opened" );
p_sys = malloc( sizeof( sout_mux_sys_t ) );
p_sys->i_streams = 0;
p_sys->idx1.i_entry_count = 0;
p_sys->idx1.i_entry_max = 10000;
- p_sys->idx1.entry = calloc( p_sys->idx1.i_entry_max, sizeof( avi_idx1_entry_t ) );
+ p_sys->idx1.entry = calloc( p_sys->idx1.i_entry_max,
+ sizeof( avi_idx1_entry_t ) );
p_sys->b_write_header = VLC_TRUE;
- msg_Info( p_mux, "Open" );
p_mux->pf_capacity = Capability;
p_mux->pf_addstream = AddStream;
p_mux->pf_delstream = DelStream;
p_mux->pf_mux = Mux;
p_mux->p_sys = p_sys;
- p_mux->i_preheader = 8; // (fourcc,length) header
-
-#if 0
- /* room to add header at the end */
- p_hdr = sout_BufferNew( p_mux->p_sout, HDR_SIZE );
- memset( p_hdr->p_buffer, 0, HDR_SIZE );
- sout_AccessOutWrite( p_mux->p_access, p_hdr );
-#endif
+ p_mux->i_preheader = 8; /* (fourcc,length) header */
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
-
static void Close( vlc_object_t * p_this )
{
sout_mux_t *p_mux = (sout_mux_t*)p_this;
sout_buffer_t *p_hdr, *p_idx1;
int i_stream;
- msg_Info( p_mux, "Close" );
+ msg_Dbg( p_mux, "AVI muxer closed" );
/* first create idx1 chunk (write at the end of the stream */
p_idx1 = avi_HeaderCreateidx1( p_mux );
(uint64_t)p_stream->i_totalsize /
(uint64_t)p_stream->i_duration;
}
- msg_Info( p_mux, "stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d",
+ msg_Info( p_mux, "stream[%d] duration:"I64Fd" totalsize:"I64Fd
+ " frames:%d fps:%f kb/s:%d",
i_stream,
(int64_t)p_stream->i_duration / (int64_t)1000000,
p_stream->i_totalsize,
sout_AccessOutWrite( p_mux->p_access, p_hdr );
}
-static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
+static int Capability( sout_mux_t *p_mux, int i_query,
+ void *p_args, void *p_answer )
{
switch( i_query )
{
p_stream->p_bih = NULL;
- p_stream->p_wf = malloc( sizeof( WAVEFORMATEX ) + p_input->p_fmt->i_extra_data );
+ p_stream->p_wf = malloc( sizeof( WAVEFORMATEX ) +
+ p_input->p_fmt->i_extra );
#define p_wf p_stream->p_wf
- p_wf->cbSize = p_input->p_fmt->i_extra_data;
+ p_wf->cbSize = p_input->p_fmt->i_extra;
if( p_wf->cbSize > 0 )
{
memcpy( &p_wf[1],
- p_input->p_fmt->p_extra_data,
- p_input->p_fmt->i_extra_data );
+ p_input->p_fmt->p_extra,
+ p_input->p_fmt->i_extra );
}
- p_wf->nChannels = p_input->p_fmt->i_channels;
- p_wf->nSamplesPerSec = p_input->p_fmt->i_sample_rate;
- p_wf->nBlockAlign = p_input->p_fmt->i_block_align;
+ p_wf->nChannels = p_input->p_fmt->audio.i_channels;
+ p_wf->nSamplesPerSec = p_input->p_fmt->audio.i_rate;
+ p_wf->nBlockAlign = p_input->p_fmt->audio.i_blockalign;
p_wf->nAvgBytesPerSec= p_input->p_fmt->i_bitrate / 8;
p_wf->wBitsPerSample = 0;
- switch( p_input->p_fmt->i_fourcc )
+ switch( p_input->p_fmt->i_codec )
{
case VLC_FOURCC( 'a', '5', '2', ' ' ):
p_wf->wFormatTag = WAVE_FORMAT_A52;
case VLC_FOURCC( 'w', 'm', 'a', '3' ):
p_wf->wFormatTag = WAVE_FORMAT_WMA3;
break;
+ /* raw codec */
+ case VLC_FOURCC( 'u', '8', ' ', ' ' ):
+ p_wf->wFormatTag = WAVE_FORMAT_PCM;
+ p_wf->nBlockAlign= p_wf->nChannels;
+ p_wf->wBitsPerSample = 8;
+ break;
+ case VLC_FOURCC( 's', '1', '6', 'l' ):
+ p_wf->wFormatTag = WAVE_FORMAT_PCM;
+ p_wf->nBlockAlign= 2 * p_wf->nChannels;
+ p_wf->wBitsPerSample = 16;
+ break;
+ case VLC_FOURCC( 's', '2', '4', 'l' ):
+ p_wf->wFormatTag = WAVE_FORMAT_PCM;
+ p_wf->nBlockAlign= 3 * p_wf->nChannels;
+ p_wf->wBitsPerSample = 24;
+ break;
+ case VLC_FOURCC( 's', '3', '2', 'l' ):
+ p_wf->wFormatTag = WAVE_FORMAT_PCM;
+ p_wf->nBlockAlign= 4 * p_wf->nChannels;
+ p_wf->wBitsPerSample = 32;
+ break;
default:
return VLC_EGENERIC;
}
p_sys->i_stream_video = p_sys->i_streams;
}
p_stream->p_wf = NULL;
- p_stream->p_bih = malloc( sizeof( BITMAPINFOHEADER ) + p_input->p_fmt->i_extra_data );
+ p_stream->p_bih = malloc( sizeof( BITMAPINFOHEADER ) +
+ p_input->p_fmt->i_extra );
#define p_bih p_stream->p_bih
- p_bih->biSize = sizeof( BITMAPINFOHEADER ) + p_input->p_fmt->i_extra_data;
- if( p_input->p_fmt->i_extra_data > 0 )
+ p_bih->biSize = sizeof( BITMAPINFOHEADER ) +
+ p_input->p_fmt->i_extra;
+ if( p_input->p_fmt->i_extra > 0 )
{
memcpy( &p_bih[1],
- p_input->p_fmt->p_extra_data,
- p_input->p_fmt->i_extra_data );
+ p_input->p_fmt->p_extra,
+ p_input->p_fmt->i_extra );
}
- p_bih->biWidth = p_input->p_fmt->i_width;
- p_bih->biHeight= p_input->p_fmt->i_height;
+ p_bih->biWidth = p_input->p_fmt->video.i_width;
+ p_bih->biHeight= p_input->p_fmt->video.i_height;
p_bih->biPlanes= 1;
p_bih->biBitCount = 24;
p_bih->biSizeImage = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
- switch( p_input->p_fmt->i_fourcc )
+ switch( p_input->p_fmt->i_codec )
{
case VLC_FOURCC( 'm', 'p', '4', 'v' ):
p_bih->biCompression = VLC_FOURCC( 'X', 'V', 'I', 'D' );
break;
default:
- p_bih->biCompression = p_input->p_fmt->i_fourcc;
+ p_bih->biCompression = p_input->p_fmt->i_codec;
break;
}
#undef p_bih
p_stream->i_totalsize = 0;
p_stream->i_frames = 0;
p_stream->i_duration = 0;
- //p_stream->i_first_pts = 0;
/* fixed later */
p_stream->f_fps = 25;
p_stream->i_bitrate = 128 * 1024;
-
p_sys->i_streams++;
return( VLC_SUCCESS );
}
msg_Dbg( p_mux, "removing input" );
- free( p_input->p_sys ); p_input->p_sys = NULL;
-
+ free( p_input->p_sys );
return( 0 );
}
if( p_data->i_length < 0 )
{
msg_Warn( p_mux, "argg length < 0 l" );
- p_data->i_length = 0;
+ sout_BufferDelete( p_mux->p_sout, p_data );
+ i_count--;
+ continue;
}
p_stream->i_duration += p_data->i_length;
p_stream->i_totalsize += p_data->i_size;
return( p_idx1 );
}
-