Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
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
Show 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