Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
266ce0f8
Commit
266ce0f8
authored
Jan 12, 2003
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* avi.c: avi muxer. (It produces broken files, but vlc is able to read
them).
parent
36f1fb3f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
670 additions
and
1 deletion
+670
-1
configure.ac.in
configure.ac.in
+1
-1
modules/mux/Modules.am
modules/mux/Modules.am
+1
-0
modules/mux/avi.c
modules/mux/avi.c
+668
-0
No files found.
configure.ac.in
View file @
266ce0f8
...
...
@@ -914,7 +914,7 @@ AC_ARG_ENABLE(sout,
if test "x${enable_sout}" != "xno"
then
PLUGINS="${PLUGINS} access_output_dummy access_output_udp access_output_file"
PLUGINS="${PLUGINS} mux_ts mux_ps mux_dummy"
PLUGINS="${PLUGINS} mux_ts mux_ps mux_
avi mux_
dummy"
PLUGINS="${PLUGINS} packetizer_mpegaudio packetizer_mpegvideo packetizer_a52"
PLUGINS="${PLUGINS} packetizer_mpeg4video packetizer_mpeg4audio"
PLUGINS="${PLUGINS} packetizer_copy"
...
...
modules/mux/Modules.am
View file @
266ce0f8
SOURCES_mux_dummy = modules/mux/dummy.c
SOURCES_mux_avi = modules/mux/avi.c
modules/mux/avi.c
0 → 100644
View file @
266ce0f8
/*****************************************************************************
* avi.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: avi.c,v 1.1 2003/01/12 04:30:14 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#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>
#elif defined( _MSC_VER ) && defined( _WIN32 ) && !defined( UNDER_CE )
# include <io.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
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
int
AddStream
(
sout_instance_t
*
,
sout_input_t
*
);
static
int
DelStream
(
sout_instance_t
*
,
sout_input_t
*
);
static
int
Mux
(
sout_instance_t
*
);
static
sout_buffer_t
*
avi_HeaderCreateRIFF
(
sout_instance_t
*
p_sout
);
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
*****************************************************************************/
vlc_module_begin
();
set_description
(
_
(
"Avi muxer"
)
);
set_capability
(
"sout mux"
,
5
);
add_shortcut
(
"avi"
);
set_callbacks
(
Open
,
Close
);
vlc_module_end
();
// FIXME FIXME
#define HDR_SIZE 10240
typedef
struct
avi_stream_s
{
int
i_cat
;
char
fcc
[
4
];
mtime_t
i_duration
;
// in s
int
i_frames
;
// total frame count
int64_t
i_totalsize
;
// total stream size
float
f_fps
;
int
i_bitrate
;
BITMAPINFOHEADER
*
p_bih
;
WAVEFORMATEX
*
p_wf
;
}
avi_stream_t
;
typedef
struct
sout_mux_s
{
int
i_streams
;
int
i_stream_video
;
off_t
i_movi_size
;
avi_stream_t
stream
[
100
];
}
sout_mux_t
;
/*****************************************************************************
* Open:
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
sout_instance_t
*
p_sout
=
(
sout_instance_t
*
)
p_this
;
sout_mux_t
*
p_mux
;
sout_buffer_t
*
p_hdr
;
p_mux
=
malloc
(
sizeof
(
sout_mux_t
)
);
p_mux
->
i_streams
=
0
;
p_mux
->
i_stream_video
=
-
1
;
p_mux
->
i_movi_size
=
0
;
msg_Info
(
p_sout
,
"Open"
);
p_sout
->
pf_mux_addstream
=
AddStream
;
p_sout
->
pf_mux_delstream
=
DelStream
;
p_sout
->
pf_mux
=
Mux
;
p_sout
->
p_mux_data
=
(
void
*
)
p_mux
;
/* room to add header at the end */
p_hdr
=
sout_BufferNew
(
p_sout
,
HDR_SIZE
);
memset
(
p_hdr
->
p_buffer
,
0
,
HDR_SIZE
);
p_sout
->
pf_write
(
p_sout
,
p_hdr
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static
void
Close
(
vlc_object_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_buffer_t
*
p_hdr
;
int
i_stream
;
msg_Info
(
p_sout
,
"Close"
);
for
(
i_stream
=
0
;
i_stream
<
p_mux
->
i_streams
;
i_stream
++
)
{
avi_stream_t
*
p_stream
;
p_stream
=
&
p_mux
->
stream
[
i_stream
];
p_stream
->
f_fps
=
25
;
if
(
p_stream
->
i_duration
>
0
)
{
p_stream
->
f_fps
=
(
float
)
p_stream
->
i_frames
/
(
(
float
)
p_stream
->
i_duration
/
(
float
)
1000000
);
}
p_stream
->
i_bitrate
=
128
*
1024
;
if
(
p_stream
->
i_duration
>
0
)
{
p_stream
->
i_bitrate
=
8
*
(
uint64_t
)
1000000
*
(
uint64_t
)
p_stream
->
i_totalsize
/
(
uint64_t
)
p_stream
->
i_duration
;
}
msg_Err
(
p_sout
,
"stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d"
,
i_stream
,
p_stream
->
i_duration
/
1000000
,
p_stream
->
i_totalsize
,
p_stream
->
i_frames
,
p_stream
->
f_fps
,
p_stream
->
i_bitrate
/
1024
);
}
p_hdr
=
avi_HeaderCreateRIFF
(
p_sout
);
p_sout
->
pf_seek
(
p_sout
,
0
);
p_sout
->
pf_write
(
p_sout
,
p_hdr
);
}
static
int
AddStream
(
sout_instance_t
*
p_sout
,
sout_input_t
*
p_input
)
{
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_sout
->
p_mux_data
;
avi_stream_t
*
p_stream
;
if
(
p_mux
->
i_streams
>=
100
)
{
msg_Err
(
p_sout
,
"too many streams"
);
return
(
-
1
);
}
if
(
p_input
->
input_format
.
p_format
==
NULL
)
{
msg_Err
(
p_sout
,
"stream descriptor missing"
);
return
(
-
1
);
}
msg_Dbg
(
p_sout
,
"adding input"
);
p_input
->
p_mux_data
=
malloc
(
sizeof
(
int
)
);
*
((
int
*
)
p_input
->
p_mux_data
)
=
p_mux
->
i_streams
;
p_stream
=
&
p_mux
->
stream
[
p_mux
->
i_streams
];
switch
(
p_input
->
input_format
.
i_cat
)
{
case
AUDIO_ES
:
{
WAVEFORMATEX
*
p_wf
=
(
WAVEFORMATEX
*
)
p_input
->
input_format
.
p_format
;
p_stream
->
i_cat
=
AUDIO_ES
;
p_stream
->
fcc
[
0
]
=
'0'
+
p_mux
->
i_streams
/
10
;
p_stream
->
fcc
[
1
]
=
'0'
+
p_mux
->
i_streams
%
10
;
p_stream
->
fcc
[
2
]
=
'w'
;
p_stream
->
fcc
[
3
]
=
'b'
;
p_stream
->
p_bih
=
NULL
;
p_stream
->
p_wf
=
malloc
(
sizeof
(
WAVEFORMATEX
)
+
p_wf
->
cbSize
);
memcpy
(
p_stream
->
p_wf
,
p_wf
,
sizeof
(
WAVEFORMATEX
)
+
p_wf
->
cbSize
);
}
break
;
case
VIDEO_ES
:
{
BITMAPINFOHEADER
*
p_bih
=
(
BITMAPINFOHEADER
*
)
p_input
->
input_format
.
p_format
;;
p_stream
->
i_cat
=
VIDEO_ES
;
p_stream
->
fcc
[
0
]
=
'0'
+
p_mux
->
i_streams
/
10
;
p_stream
->
fcc
[
1
]
=
'0'
+
p_mux
->
i_streams
%
10
;
p_stream
->
fcc
[
2
]
=
'd'
;
p_stream
->
fcc
[
3
]
=
'c'
;
if
(
p_mux
->
i_stream_video
<
0
)
{
p_mux
->
i_stream_video
=
p_mux
->
i_streams
;
}
p_stream
->
p_wf
=
NULL
;
p_stream
->
p_bih
=
malloc
(
p_bih
->
biSize
);
memcpy
(
p_stream
->
p_bih
,
p_bih
,
p_bih
->
biSize
);
}
break
;
default:
return
(
-
1
);
}
p_stream
->
i_totalsize
=
0
;
p_stream
->
i_frames
=
0
;
p_stream
->
i_duration
=
0
;
p_mux
->
i_streams
++
;
return
(
0
);
}
static
int
DelStream
(
sout_instance_t
*
p_sout
,
sout_input_t
*
p_input
)
{
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
msg_Dbg
(
p_sout
,
"removing input"
);
free
(
p_input
->
p_mux_data
);
p_input
->
p_mux_data
=
NULL
;
return
(
0
);
}
static
int
Mux
(
sout_instance_t
*
p_sout
)
{
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_sout
->
p_mux_data
;
avi_stream_t
*
p_stream
;
int
i_stream
;
int
i
;
for
(
i
=
0
;
i
<
p_sout
->
i_nb_inputs
;
i
++
)
{
int
i_count
;
sout_fifo_t
*
p_fifo
;
i_stream
=
*
((
int
*
)
p_sout
->
pp_inputs
[
i
]
->
p_mux_data
);
p_stream
=
&
p_mux
->
stream
[
i_stream
];
p_fifo
=
p_sout
->
pp_inputs
[
i
]
->
p_fifo
;
i_count
=
p_fifo
->
i_depth
;
while
(
i_count
>
0
)
{
sout_buffer_t
*
p_data
;
sout_buffer_t
*
p_hdr
;
p_data
=
sout_FifoGet
(
p_fifo
);
p_stream
->
i_frames
++
;
p_stream
->
i_duration
+=
p_data
->
i_length
;
p_stream
->
i_totalsize
+=
p_data
->
i_size
;
p_hdr
=
sout_BufferNew
(
p_sout
,
8
);
SetFCC
(
p_hdr
->
p_buffer
,
p_stream
->
fcc
);
SetDWLE
(
p_hdr
->
p_buffer
+
4
,
p_data
->
i_size
);
if
(
p_data
->
i_size
&
0x01
)
{
sout_BufferRealloc
(
p_sout
,
p_data
,
p_data
->
i_size
+
1
);
p_data
->
i_size
+=
1
;
}
p_sout
->
pf_write
(
p_sout
,
p_hdr
);
p_mux
->
i_movi_size
+=
p_hdr
->
i_size
;
p_sout
->
pf_write
(
p_sout
,
p_data
);
p_mux
->
i_movi_size
+=
p_data
->
i_size
;
i_count
--
;
}
}
return
(
0
);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
typedef
struct
buffer_out_s
{
int
i_buffer_size
;
int
i_buffer
;
uint8_t
*
p_buffer
;
}
buffer_out_t
;
static
void
bo_Init
(
buffer_out_t
*
p_bo
,
int
i_size
,
uint8_t
*
p_buffer
)
{
p_bo
->
i_buffer_size
=
i_size
;
p_bo
->
i_buffer
=
0
;
p_bo
->
p_buffer
=
p_buffer
;
}
static
void
bo_AddByte
(
buffer_out_t
*
p_bo
,
uint8_t
i
)
{
if
(
p_bo
->
i_buffer
<
p_bo
->
i_buffer_size
)
{
p_bo
->
p_buffer
[
p_bo
->
i_buffer
]
=
i
;
}
p_bo
->
i_buffer
++
;
}
static
void
bo_AddWordLE
(
buffer_out_t
*
p_bo
,
uint16_t
i
)
{
bo_AddByte
(
p_bo
,
i
&
0xff
);
bo_AddByte
(
p_bo
,
(
(
i
>>
8
)
&
0xff
)
);
}
static
void
bo_AddWordBE
(
buffer_out_t
*
p_bo
,
uint16_t
i
)
{
bo_AddByte
(
p_bo
,
(
(
i
>>
8
)
&
0xff
)
);
bo_AddByte
(
p_bo
,
i
&
0xff
);
}
static
void
bo_AddDWordLE
(
buffer_out_t
*
p_bo
,
uint32_t
i
)
{
bo_AddWordLE
(
p_bo
,
i
&
0xffff
);
bo_AddWordLE
(
p_bo
,
(
(
i
>>
16
)
&
0xffff
)
);
}
static
void
bo_AddDWordBE
(
buffer_out_t
*
p_bo
,
uint32_t
i
)
{
bo_AddWordLE
(
p_bo
,
(
(
i
>>
16
)
&
0xffff
)
);
bo_AddWordLE
(
p_bo
,
i
&
0xffff
);
}
#if 0
static void bo_AddLWordLE( buffer_out_t *p_bo, uint64_t i )
{
bo_AddDWordLE( p_bo, i &0xffffffff );
bo_AddDWordLE( p_bo, ( ( i >> 32) &0xffffffff ) );
}
static void bo_AddLWordBE( buffer_out_t *p_bo, uint64_t i )
{
bo_AddDWordBE( p_bo, ( ( i >> 32) &0xffffffff ) );
bo_AddDWordBE( p_bo, i &0xffffffff );
}
#endif
static
void
bo_AddFCC
(
buffer_out_t
*
p_bo
,
char
*
fcc
)
{
bo_AddByte
(
p_bo
,
fcc
[
0
]
);
bo_AddByte
(
p_bo
,
fcc
[
1
]
);
bo_AddByte
(
p_bo
,
fcc
[
2
]
);
bo_AddByte
(
p_bo
,
fcc
[
3
]
);
}
static
void
bo_AddMem
(
buffer_out_t
*
p_bo
,
int
i_size
,
uint8_t
*
p_mem
)
{
int
i
;
for
(
i
=
0
;
i
<
i_size
;
i
++
)
{
bo_AddByte
(
p_bo
,
p_mem
[
i
]
);
}
}
/****************************************************************************
****************************************************************************
**
** avi header generation
**
****************************************************************************
****************************************************************************/
#define AVI_BOX_ENTER( fcc ) \
buffer_out_t _bo_sav_; \
bo_AddFCC( p_bo, fcc ); \
_bo_sav_ = *p_bo; \
bo_AddDWordLE( p_bo, 0 )
#define AVI_BOX_ENTER_LIST( fcc ) \
AVI_BOX_ENTER( "LIST" ); \
bo_AddFCC( p_bo, fcc )
#define AVI_BOX_EXIT( i_err ) \
if( p_bo->i_buffer&0x01 ) bo_AddByte( p_bo, 0 ); \
bo_AddDWordLE( &_bo_sav_, p_bo->i_buffer - _bo_sav_.i_buffer - 4 ); \
return( i_err );
static
int
avi_HeaderAdd_avih
(
sout_instance_t
*
p_sout
,
buffer_out_t
*
p_bo
)
{
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_sout
->
p_mux_data
;
avi_stream_t
*
p_video
=
NULL
;
int
i_stream
;
uint32_t
i_microsecperframe
;
int
i_maxbytespersec
;
int
i_totalframes
;
AVI_BOX_ENTER
(
"avih"
);
if
(
p_mux
->
i_stream_video
>=
0
)
{
p_video
=
&
p_mux
->
stream
[
p_mux
->
i_stream_video
];
if
(
p_video
->
i_frames
<=
0
)
{
p_video
=
NULL
;
}
}
if
(
p_video
)
{
i_microsecperframe
=
(
uint32_t
)(
(
float
)
1000000
/
(
float
)
p_mux
->
stream
[
p_mux
->
i_stream_video
].
f_fps
);
i_totalframes
=
p_mux
->
stream
[
p_mux
->
i_stream_video
].
i_frames
;
}
else
{
msg_Warn
(
p_sout
,
"avi file without audio video track isn't a good idea..."
);
i_microsecperframe
=
0
;
i_totalframes
=
0
;
}
for
(
i_stream
=
0
,
i_maxbytespersec
=
0
;
i_stream
<
p_mux
->
i_streams
;
i_stream
++
)
{
if
(
p_mux
->
stream
[
p_mux
->
i_stream_video
].
i_duration
>
0
)
{
i_maxbytespersec
+=
p_mux
->
stream
[
p_mux
->
i_stream_video
].
i_totalsize
/
p_mux
->
stream
[
p_mux
->
i_stream_video
].
i_duration
;
}
}
bo_AddDWordLE
(
p_bo
,
i_microsecperframe
);
bo_AddDWordLE
(
p_bo
,
i_maxbytespersec
);
bo_AddDWordLE
(
p_bo
,
0
);
/* padding */
bo_AddDWordLE
(
p_bo
,
AVIF_TRUSTCKTYPE
|
AVIF_HASINDEX
|
AVIF_ISINTERLEAVED
);
/* flags */
bo_AddDWordLE
(
p_bo
,
i_totalframes
);
bo_AddDWordLE
(
p_bo
,
0
);
/* initial frame */
bo_AddDWordLE
(
p_bo
,
p_mux
->
i_streams
);
/* streams count */
bo_AddDWordLE
(
p_bo
,
1024
*
1024
);
/* suggested buffer size */
if
(
p_video
)
{
bo_AddDWordLE
(
p_bo
,
p_video
->
p_bih
->
biWidth
);
bo_AddDWordLE
(
p_bo
,
p_video
->
p_bih
->
biHeight
);
}
else
{
bo_AddDWordLE
(
p_bo
,
0
);
bo_AddDWordLE
(
p_bo
,
0
);
}
bo_AddDWordLE
(
p_bo
,
0
);
/* ???? */
bo_AddDWordLE
(
p_bo
,
0
);
/* ???? */
bo_AddDWordLE
(
p_bo
,
0
);
/* ???? */
bo_AddDWordLE
(
p_bo
,
0
);
/* ???? */
AVI_BOX_EXIT
(
0
);
}
static
int
avi_HeaderAdd_strh
(
sout_instance_t
*
p_sout
,
buffer_out_t
*
p_bo
,
avi_stream_t
*
p_stream
)
{
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER
(
"strh"
);
switch
(
p_stream
->
i_cat
)
{
case
VIDEO_ES
:
{
bo_AddFCC
(
p_bo
,
"vids"
);
bo_AddDWordBE
(
p_bo
,
p_stream
->
p_bih
->
biCompression
);
bo_AddDWordLE
(
p_bo
,
0
);
/* flags */
bo_AddWordLE
(
p_bo
,
0
);
/* priority */
bo_AddWordLE
(
p_bo
,
0
);
/* langage */
bo_AddDWordLE
(
p_bo
,
0
);
/* initial frame */
bo_AddDWordLE
(
p_bo
,
1000
);
/* scale */
bo_AddDWordLE
(
p_bo
,
(
uint32_t
)(
1000
*
p_stream
->
f_fps
));
bo_AddDWordLE
(
p_bo
,
0
);
/* start */
bo_AddDWordLE
(
p_bo
,
p_stream
->
i_frames
);
bo_AddDWordLE
(
p_bo
,
1024
*
1024
);
bo_AddDWordLE
(
p_bo
,
-
1
);
/* quality */
bo_AddDWordLE
(
p_bo
,
0
);
/* samplesize */
bo_AddWordLE
(
p_bo
,
0
);
/* ??? */
bo_AddWordLE
(
p_bo
,
0
);
/* ??? */
bo_AddWordLE
(
p_bo
,
p_stream
->
p_bih
->
biWidth
);
bo_AddWordLE
(
p_bo
,
p_stream
->
p_bih
->
biHeight
);
}
break
;
case
AUDIO_ES
:
{
int
i_rate
,
i_scale
,
i_samplesize
;
i_samplesize
=
p_stream
->
p_wf
->
nBlockAlign
;
if
(
i_samplesize
>
1
)
{
i_scale
=
i_samplesize
;
i_rate
=
i_scale
*
p_stream
->
i_bitrate
/
8
;
}
else
{
i_samplesize
=
1
;
i_scale
=
1000
;
i_rate
=
1000
*
p_stream
->
i_bitrate
/
8
;
}
bo_AddFCC
(
p_bo
,
"auds"
);
bo_AddDWordLE
(
p_bo
,
1
);
/* tag */
bo_AddDWordLE
(
p_bo
,
0
);
/* flags */
bo_AddWordLE
(
p_bo
,
0
);
/* priority */
bo_AddWordLE
(
p_bo
,
0
);
/* langage */
bo_AddDWordLE
(
p_bo
,
0
);
/* initial frame */
bo_AddDWordLE
(
p_bo
,
i_scale
);
/* scale */
bo_AddDWordLE
(
p_bo
,
i_rate
);
bo_AddDWordLE
(
p_bo
,
0
);
/* start */
bo_AddDWordLE
(
p_bo
,
p_stream
->
i_frames
);
bo_AddDWordLE
(
p_bo
,
10
*
1024
);
bo_AddDWordLE
(
p_bo
,
-
1
);
/* quality */
bo_AddDWordLE
(
p_bo
,
i_samplesize
);
bo_AddWordLE
(
p_bo
,
0
);
/* ??? */
bo_AddWordLE
(
p_bo
,
0
);
/* ??? */
bo_AddWordLE
(
p_bo
,
0
);
bo_AddWordLE
(
p_bo
,
0
);
}
break
;
}
AVI_BOX_EXIT
(
0
);
}
static
int
avi_HeaderAdd_strf
(
sout_instance_t
*
p_sout
,
buffer_out_t
*
p_bo
,
avi_stream_t
*
p_stream
)
{
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER
(
"strf"
);
switch
(
p_stream
->
i_cat
)
{
case
AUDIO_ES
:
bo_AddWordLE
(
p_bo
,
p_stream
->
p_wf
->
wFormatTag
);
bo_AddWordLE
(
p_bo
,
p_stream
->
p_wf
->
nChannels
);
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_wf
->
nSamplesPerSec
);
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_wf
->
nAvgBytesPerSec
);
bo_AddWordLE
(
p_bo
,
p_stream
->
p_wf
->
nBlockAlign
);
bo_AddWordLE
(
p_bo
,
p_stream
->
p_wf
->
wBitsPerSample
);
bo_AddWordLE
(
p_bo
,
p_stream
->
p_wf
->
cbSize
);
bo_AddMem
(
p_bo
,
p_stream
->
p_wf
->
cbSize
,
(
uint8_t
*
)
&
p_stream
->
p_wf
[
1
]
);
break
;
case
VIDEO_ES
:
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_bih
->
biSize
);
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_bih
->
biWidth
);
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
->
biBitCount
);
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_bih
->
biCompression
);
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
->
biYPelsPerMeter
);
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_bih
->
biClrUsed
);
bo_AddDWordLE
(
p_bo
,
p_stream
->
p_bih
->
biClrImportant
);
bo_AddMem
(
p_bo
,
p_stream
->
p_bih
->
biSize
-
sizeof
(
BITMAPINFOHEADER
),
(
uint8_t
*
)
&
p_stream
->
p_bih
[
1
]
);
break
;
}
AVI_BOX_EXIT
(
0
);
}
static
int
avi_HeaderAdd_strl
(
sout_instance_t
*
p_sout
,
buffer_out_t
*
p_bo
,
avi_stream_t
*
p_stream
)
{
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER_LIST
(
"strl"
);
avi_HeaderAdd_strh
(
p_sout
,
p_bo
,
p_stream
);
avi_HeaderAdd_strf
(
p_sout
,
p_bo
,
p_stream
);
AVI_BOX_EXIT
(
0
);
}
static
sout_buffer_t
*
avi_HeaderCreateRIFF
(
sout_instance_t
*
p_sout
)
{
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_sout
->
p_mux_data
;
sout_buffer_t
*
p_hdr
;
int
i_stream
;
int
i_maxbytespersec
;
int
i_junk
;
buffer_out_t
bo
;
p_hdr
=
sout_BufferNew
(
p_sout
,
HDR_SIZE
);
memset
(
p_hdr
->
p_buffer
,
0
,
HDR_SIZE
);
bo_Init
(
&
bo
,
HDR_SIZE
,
p_hdr
->
p_buffer
);
bo_AddFCC
(
&
bo
,
"RIFF"
);
bo_AddDWordLE
(
&
bo
,
p_mux
->
i_movi_size
+
HDR_SIZE
-
8
);
bo_AddFCC
(
&
bo
,
"AVI "
);
bo_AddFCC
(
&
bo
,
"LIST"
);
bo_AddDWordLE
(
&
bo
,
HDR_SIZE
-
8
);
bo_AddFCC
(
&
bo
,
"hdrl"
);
avi_HeaderAdd_avih
(
p_sout
,
&
bo
);
for
(
i_stream
=
0
,
i_maxbytespersec
=
0
;
i_stream
<
p_mux
->
i_streams
;
i_stream
++
)
{
avi_HeaderAdd_strl
(
p_sout
,
&
bo
,
&
p_mux
->
stream
[
i_stream
]
);
}
i_junk
=
HDR_SIZE
-
bo
.
i_buffer
-
8
-
12
;
bo_AddFCC
(
&
bo
,
"JUNK"
);
bo_AddDWordLE
(
&
bo
,
i_junk
);
bo
.
i_buffer
+=
i_junk
;
bo_AddFCC
(
&
bo
,
"LIST"
);
bo_AddDWordLE
(
&
bo
,
p_mux
->
i_movi_size
);
bo_AddFCC
(
&
bo
,
"movi"
);
return
(
p_hdr
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment