Commit c4682242 authored by Laurent Aimar's avatar Laurent Aimar

* mux/avi.c: added index creation.

 * demux/avi.c: fix stream length calculation.
 * stream_output.c: forgot a return value ...
parent 9d72fcf7
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc * avi.c : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: avi.c,v 1.24 2003/01/12 18:26:09 fenrir Exp $ * $Id: avi.c,v 1.25 2003/01/13 04:46:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -725,7 +725,7 @@ static mtime_t AVI_MovieGetLength( input_thread_t *p_input, demux_sys_t *p_avi ...@@ -725,7 +725,7 @@ static mtime_t AVI_MovieGetLength( input_thread_t *p_input, demux_sys_t *p_avi
{ {
i_length = i_length =
(mtime_t)( p_stream->p_index[p_stream->i_idxnb-1].i_lengthtotal + (mtime_t)( p_stream->p_index[p_stream->i_idxnb-1].i_lengthtotal +
p_stream->p_index[p_stream->i_idxnb-1].i_length ) / p_stream->p_index[p_stream->i_idxnb-1].i_length ) *
(mtime_t)p_stream->i_scale / (mtime_t)p_stream->i_scale /
(mtime_t)p_stream->i_rate / (mtime_t)p_stream->i_rate /
(mtime_t)p_stream->i_samplesize; (mtime_t)p_stream->i_samplesize;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c * avi.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: avi.c,v 1.2 2003/01/13 02:33:13 fenrir Exp $ * $Id: avi.c,v 1.3 2003/01/13 04:46:49 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
/* TODO: add OpenDML write support */
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
...@@ -51,6 +53,12 @@ ...@@ -51,6 +53,12 @@
#define AVIF_WASCAPTUREFILE 0x00010000 #define AVIF_WASCAPTUREFILE 0x00010000
#define AVIF_COPYRIGHTED 0x00020000 #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 * Exported prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -62,6 +70,7 @@ static int DelStream( sout_instance_t *, sout_input_t * ); ...@@ -62,6 +70,7 @@ static int DelStream( sout_instance_t *, sout_input_t * );
static int Mux ( sout_instance_t * ); static int Mux ( sout_instance_t * );
static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ); static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout );
static sout_buffer_t *avi_HeaderCreateidx1( sout_instance_t *p_sout );
static void SetFCC( uint8_t *p, char *fcc ) static void SetFCC( uint8_t *p, char *fcc )
{ {
...@@ -111,6 +120,23 @@ typedef struct avi_stream_s ...@@ -111,6 +120,23 @@ typedef struct avi_stream_s
} avi_stream_t; } avi_stream_t;
typedef struct avi_idx1_entry_s
{
char fcc[4];
uint32_t i_flags;
uint32_t i_pos;
uint32_t i_length;
} avi_idx1_entry_t;
typedef struct avi_idx1_s
{
unsigned int i_entry_count;
unsigned int i_entry_max;
avi_idx1_entry_t *entry;
} avi_idx1_t;
typedef struct sout_mux_s typedef struct sout_mux_s
{ {
int i_streams; int i_streams;
...@@ -119,6 +145,9 @@ typedef struct sout_mux_s ...@@ -119,6 +145,9 @@ typedef struct sout_mux_s
off_t i_movi_size; off_t i_movi_size;
avi_stream_t stream[100]; avi_stream_t stream[100];
avi_idx1_t idx1;
off_t i_idx1_size;
} sout_mux_t; } sout_mux_t;
/***************************************************************************** /*****************************************************************************
...@@ -135,6 +164,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -135,6 +164,10 @@ static int Open( vlc_object_t *p_this )
p_mux->i_stream_video = -1; p_mux->i_stream_video = -1;
p_mux->i_movi_size = 0; p_mux->i_movi_size = 0;
p_mux->idx1.i_entry_count = 0;
p_mux->idx1.i_entry_max = 10000;
p_mux->idx1.entry = calloc( p_mux->idx1.i_entry_max, sizeof( avi_idx1_entry_t ) );
msg_Info( p_sout, "Open" ); msg_Info( p_sout, "Open" );
p_sout->pf_mux_addstream = AddStream; p_sout->pf_mux_addstream = AddStream;
...@@ -159,11 +192,17 @@ static void Close( vlc_object_t * p_this ) ...@@ -159,11 +192,17 @@ static void Close( vlc_object_t * p_this )
{ {
sout_instance_t *p_sout = (sout_instance_t*)p_this; sout_instance_t *p_sout = (sout_instance_t*)p_this;
sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
sout_buffer_t *p_hdr; sout_buffer_t *p_hdr, *p_idx1;
int i_stream; int i_stream;
msg_Info( p_sout, "Close" ); msg_Info( p_sout, "Close" );
/* first create idx1 chunk (write at the end of the stream */
p_idx1 = avi_HeaderCreateidx1( p_sout );
p_mux->i_idx1_size = p_idx1->i_size;
p_sout->pf_write( p_sout, p_idx1 );
/* calculate some value for headers creations */
for( i_stream = 0; i_stream < p_mux->i_streams; i_stream++ ) for( i_stream = 0; i_stream < p_mux->i_streams; i_stream++ )
{ {
avi_stream_t *p_stream; avi_stream_t *p_stream;
...@@ -302,6 +341,7 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -302,6 +341,7 @@ static int Mux ( sout_instance_t *p_sout )
i_count = p_fifo->i_depth; i_count = p_fifo->i_depth;
while( i_count > 0 ) while( i_count > 0 )
{ {
avi_idx1_entry_t *p_idx;
sout_buffer_t *p_data; sout_buffer_t *p_data;
p_data = sout_FifoGet( p_fifo ); p_data = sout_FifoGet( p_fifo );
...@@ -310,6 +350,21 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -310,6 +350,21 @@ static int Mux ( sout_instance_t *p_sout )
p_stream->i_duration += p_data->i_length; p_stream->i_duration += p_data->i_length;
p_stream->i_totalsize += p_data->i_size; p_stream->i_totalsize += p_data->i_size;
/* add idx1 entry for this frame */
p_idx = &p_mux->idx1.entry[p_mux->idx1.i_entry_count];
memcpy( p_idx->fcc, p_stream->fcc, 4 );
p_idx->i_flags = AVIIF_KEYFRAME;
p_idx->i_pos = p_mux->i_movi_size + 4;
p_idx->i_length= p_data->i_size;
p_mux->idx1.i_entry_count++;
if( p_mux->idx1.i_entry_count >= p_mux->idx1.i_entry_max )
{
p_mux->idx1.i_entry_max += 10000;
p_mux->idx1.entry = realloc( p_mux->idx1.entry,
p_mux->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) );
}
if( sout_BufferReallocFromPreHeader( p_sout, p_data, 8 ) ) if( sout_BufferReallocFromPreHeader( p_sout, p_data, 8 ) )
{ {
/* there isn't enough data in preheader */ /* there isn't enough data in preheader */
...@@ -389,8 +444,8 @@ static void bo_AddDWordLE( buffer_out_t *p_bo, uint32_t i ) ...@@ -389,8 +444,8 @@ static void bo_AddDWordLE( buffer_out_t *p_bo, uint32_t i )
} }
static void bo_AddDWordBE( buffer_out_t *p_bo, uint32_t i ) static void bo_AddDWordBE( buffer_out_t *p_bo, uint32_t i )
{ {
bo_AddWordLE( p_bo, ( ( i >> 16) &0xffff ) ); bo_AddWordBE( p_bo, ( ( i >> 16) &0xffff ) );
bo_AddWordLE( p_bo, i &0xffff ); bo_AddWordBE( p_bo, i &0xffff );
} }
#if 0 #if 0
static void bo_AddLWordLE( buffer_out_t *p_bo, uint64_t i ) static void bo_AddLWordLE( buffer_out_t *p_bo, uint64_t i )
...@@ -563,7 +618,7 @@ static int avi_HeaderAdd_strh( sout_instance_t *p_sout, ...@@ -563,7 +618,7 @@ static int avi_HeaderAdd_strh( sout_instance_t *p_sout,
i_rate = 1000 * p_stream->i_bitrate / 8; i_rate = 1000 * p_stream->i_bitrate / 8;
} }
bo_AddFCC( p_bo, "auds" ); bo_AddFCC( p_bo, "auds" );
bo_AddDWordLE( p_bo, 1 ); /* tag */ bo_AddDWordLE( p_bo, 0 ); /* tag */
bo_AddDWordLE( p_bo, 0 ); /* flags */ bo_AddDWordLE( p_bo, 0 ); /* flags */
bo_AddWordLE( p_bo, 0 ); /* priority */ bo_AddWordLE( p_bo, 0 ); /* priority */
bo_AddWordLE( p_bo, 0 ); /* langage */ bo_AddWordLE( p_bo, 0 ); /* langage */
...@@ -611,7 +666,7 @@ static int avi_HeaderAdd_strf( sout_instance_t *p_sout, ...@@ -611,7 +666,7 @@ static int avi_HeaderAdd_strf( sout_instance_t *p_sout,
bo_AddDWordLE( p_bo, p_stream->p_bih->biHeight ); bo_AddDWordLE( p_bo, p_stream->p_bih->biHeight );
bo_AddWordLE( p_bo, p_stream->p_bih->biPlanes ); bo_AddWordLE( p_bo, p_stream->p_bih->biPlanes );
bo_AddWordLE( p_bo, p_stream->p_bih->biBitCount ); bo_AddWordLE( p_bo, p_stream->p_bih->biBitCount );
bo_AddDWordLE( p_bo, p_stream->p_bih->biCompression ); bo_AddDWordBE( p_bo, p_stream->p_bih->biCompression );
bo_AddDWordLE( p_bo, p_stream->p_bih->biSizeImage ); bo_AddDWordLE( p_bo, p_stream->p_bih->biSizeImage );
bo_AddDWordLE( p_bo, p_stream->p_bih->biXPelsPerMeter ); bo_AddDWordLE( p_bo, p_stream->p_bih->biXPelsPerMeter );
bo_AddDWordLE( p_bo, p_stream->p_bih->biYPelsPerMeter ); bo_AddDWordLE( p_bo, p_stream->p_bih->biYPelsPerMeter );
...@@ -654,7 +709,7 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ) ...@@ -654,7 +709,7 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout )
bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer ); bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer );
bo_AddFCC( &bo, "RIFF" ); bo_AddFCC( &bo, "RIFF" );
bo_AddDWordLE( &bo, p_mux->i_movi_size + HDR_SIZE - 8 ); bo_AddDWordLE( &bo, p_mux->i_movi_size + HDR_SIZE - 8 + p_mux->i_idx1_size );
bo_AddFCC( &bo, "AVI " ); bo_AddFCC( &bo, "AVI " );
bo_AddFCC( &bo, "LIST" ); bo_AddFCC( &bo, "LIST" );
...@@ -673,8 +728,38 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ) ...@@ -673,8 +728,38 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout )
bo.i_buffer += i_junk; bo.i_buffer += i_junk;
bo_AddFCC( &bo, "LIST" ); bo_AddFCC( &bo, "LIST" );
bo_AddDWordLE( &bo, p_mux->i_movi_size); bo_AddDWordLE( &bo, p_mux->i_movi_size + 4 );
bo_AddFCC( &bo, "movi" ); bo_AddFCC( &bo, "movi" );
return( p_hdr ); return( p_hdr );
} }
static sout_buffer_t * avi_HeaderCreateidx1( sout_instance_t *p_sout )
{
sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
sout_buffer_t *p_idx1;
uint32_t i_idx1_size;
unsigned int i;
buffer_out_t bo;
i_idx1_size = 16 * p_mux->idx1.i_entry_count;
p_idx1 = sout_BufferNew( p_sout, i_idx1_size + 8 );
memset( p_idx1->p_buffer, 0, i_idx1_size );
bo_Init( &bo, i_idx1_size, p_idx1->p_buffer );
bo_AddFCC( &bo, "idx1" );
bo_AddDWordLE( &bo, i_idx1_size );
for( i = 0; i < p_mux->idx1.i_entry_count; i++ )
{
bo_AddFCC( &bo, p_mux->idx1.entry[i].fcc );
bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_flags );
bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_pos );
bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_length );
}
return( p_idx1 );
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* stream_output.c : stream output module * stream_output.c : stream output module
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: stream_output.c,v 1.9 2003/01/13 02:33:13 fenrir Exp $ * $Id: stream_output.c,v 1.10 2003/01/13 04:46:49 fenrir Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr> * Laurent Aimar <fenrir@via.ecp.fr>
...@@ -555,6 +555,8 @@ int sout_BufferReallocFromPreHeader( sout_instance_t *p_sout, sout_buffer_t *p_b ...@@ -555,6 +555,8 @@ int sout_BufferReallocFromPreHeader( sout_instance_t *p_sout, sout_buffer_t *p_b
p_buffer->p_buffer -= i_size; p_buffer->p_buffer -= i_size;
p_buffer->i_size += i_size; p_buffer->i_size += i_size;
p_buffer->i_buffer_size += i_size; p_buffer->i_buffer_size += i_size;
return( 0 );
} }
int sout_BufferDelete( sout_instance_t *p_sout, sout_buffer_t *p_buffer ) int sout_BufferDelete( sout_instance_t *p_sout, sout_buffer_t *p_buffer )
......
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