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
706297b3
Commit
706297b3
authored
Oct 15, 2002
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* all : forgot to add theses new files :p
parent
9295116d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1343 additions
and
0 deletions
+1343
-0
modules/demux/avi/libavi.c
modules/demux/avi/libavi.c
+987
-0
modules/demux/avi/libavi.h
modules/demux/avi/libavi.h
+356
-0
No files found.
modules/demux/avi/libavi.c
0 → 100644
View file @
706297b3
/*****************************************************************************
* libavi.c :
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libavi.c,v 1.1 2002/10/15 00:56:43 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.
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
/* strdup() */
#include <errno.h>
#include <sys/types.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include "libavi.h"
#define AVI_DEBUG 1
#define AVIFOURCC_PRINT( x ) \
(x)&0xff, \
( (x) >> 8 )&0xff, \
( (x) >> 16 )&0xff, \
( (x) >> 24 )&0xff
#define FREE( p ) \
if( p ) {free( p ); p = NULL; }
#define __EVEN( x ) ( (x)&0x01 ? (x)+1 : (x) )
/* Some functions to manipulate memory */
static
u16
GetWLE
(
u8
*
p_buff
)
{
return
(
(
p_buff
[
0
])
+
(
p_buff
[
1
]
<<
8
)
);
}
static
u32
GetDWLE
(
u8
*
p_buff
)
{
return
(
p_buff
[
0
]
+
(
p_buff
[
1
]
<<
8
)
+
(
p_buff
[
2
]
<<
16
)
+
(
p_buff
[
3
]
<<
24
)
);
}
static
vlc_fourcc_t
GetFOURCC
(
byte_t
*
p_buff
)
{
return
(
VLC_FOURCC
(
p_buff
[
0
],
p_buff
[
1
],
p_buff
[
2
],
p_buff
[
3
]
)
);
}
/*****************************************************************************
* Some basic functions to manipulate stream more easily in vlc
*
* AVI_TellAbsolute get file position
*
* AVI_SeekAbsolute seek in the file
*
* AVI_ReadData read data from the file in a buffer
*
* AVI_SkipBytes skip bytes
*
*****************************************************************************/
off_t
AVI_TellAbsolute
(
input_thread_t
*
p_input
)
{
off_t
i_pos
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
i_pos
=
p_input
->
stream
.
p_selected_area
->
i_tell
-
(
p_input
->
p_last_data
-
p_input
->
p_current_data
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
(
i_pos
);
}
int
AVI_SeekAbsolute
(
input_thread_t
*
p_input
,
off_t
i_pos
)
{
off_t
i_filepos
;
if
(
i_pos
>=
p_input
->
stream
.
p_selected_area
->
i_size
)
{
return
(
0
);
}
i_filepos
=
AVI_TellAbsolute
(
p_input
);
if
(
i_filepos
==
i_pos
)
{
return
(
1
);
}
if
(
p_input
->
stream
.
b_seekable
&&
p_input
->
stream
.
i_method
==
INPUT_METHOD_FILE
)
{
p_input
->
pf_seek
(
p_input
,
i_pos
);
input_AccessReinit
(
p_input
);
return
(
1
);
}
else
{
int
i_peek
;
int
i_skip
=
i_pos
-
i_filepos
;
u8
*
p_peek
;
msg_Warn
(
p_input
,
"will skip %d bytes, slow"
,
i_skip
);
if
(
i_skip
<
0
)
{
return
(
0
);
// failed
}
while
(
i_skip
>
0
)
{
i_peek
=
input_Peek
(
p_input
,
&
p_peek
,
i_skip
+
1
);
i_peek
--
;
i_skip
-=
i_peek
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
p_current_data
+=
i_peek
;
// skip them
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
if
(
i_peek
<=
0
)
{
return
(
0
);
}
}
return
(
1
);
}
}
/* return 1 if success, 0 if fail */
int
AVI_ReadData
(
input_thread_t
*
p_input
,
u8
*
p_buff
,
int
i_size
)
{
data_packet_t
*
p_data
;
int
i_count
;
int
i_read
=
0
;
if
(
!
i_size
)
{
return
(
0
);
}
do
{
i_count
=
input_SplitBuffer
(
p_input
,
&
p_data
,
__MIN
(
i_size
,
1024
)
);
if
(
i_count
<=
0
)
{
return
(
i_read
);
}
memcpy
(
p_buff
,
p_data
->
p_payload_start
,
i_count
);
input_DeletePacket
(
p_input
->
p_method_data
,
p_data
);
p_buff
+=
i_count
;
i_size
-=
i_count
;
i_read
+=
i_count
;
}
while
(
i_size
);
return
(
i_read
);
}
int
AVI_SkipBytes
(
input_thread_t
*
p_input
,
int
i_count
)
{
int
i_buff_size
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
i_buff_size
=
p_input
->
p_last_data
-
p_input
->
p_current_data
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
if
(
i_count
>
0
&&
i_count
+
1
<
i_buff_size
)
{
u8
*
p_peek
;
input_Peek
(
p_input
,
&
p_peek
,
i_count
+
1
);
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
p_current_data
+=
i_count
;
// skip them
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
(
1
);
}
else
{
return
(
AVI_SeekAbsolute
(
p_input
,
AVI_TellAbsolute
(
p_input
)
+
i_count
)
);
}
}
/*****************************************************************************
*
* AVI_TestFile: look at first bytes to see if it's a valid avi file
*
* unseekable: ok
*
*****************************************************************************/
int
AVI_TestFile
(
input_thread_t
*
p_input
)
{
u8
*
p_peek
;
if
(
input_Peek
(
p_input
,
&
p_peek
,
8
)
<
8
)
{
msg_Err
(
p_input
,
"cannot peek()"
);
return
(
0
);
}
if
(
GetDWLE
(
p_peek
)
==
AVIFOURCC_RIFF
&&
GetDWLE
(
p_peek
+
8
)
==
AVIFOURCC_AVI
)
{
return
(
1
);
}
else
{
return
(
0
);
}
}
/****************************************************************************
*
* Basics functions to manipulates chunks
*
****************************************************************************/
static
int
AVI_ChunkReadCommon
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
u8
*
p_peek
;
int
i_peek
;
memset
(
p_chk
,
0
,
sizeof
(
avi_chunk_t
)
);
if
(
(
i_peek
=
input_Peek
(
p_input
,
&
p_peek
,
8
)
)
<
8
)
{
return
(
0
);
}
p_chk
->
common
.
i_chunk_fourcc
=
GetDWLE
(
p_peek
);
p_chk
->
common
.
i_chunk_size
=
GetDWLE
(
p_peek
+
4
);
p_chk
->
common
.
i_chunk_pos
=
AVI_TellAbsolute
(
p_input
);
p_chk
->
common
.
p_father
=
NULL
;
p_chk
->
common
.
p_next
=
NULL
;
p_chk
->
common
.
p_first
=
NULL
;
p_chk
->
common
.
p_next
=
NULL
;
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"Found Chunk fourcc:%c%c%c%c size:%lld pos:%lld"
,
AVIFOURCC_PRINT
(
p_chk
->
common
.
i_chunk_fourcc
),
p_chk
->
common
.
i_chunk_size
,
p_chk
->
common
.
i_chunk_pos
);
#endif
return
(
1
);
}
static
int
AVI_NextChunk
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
avi_chunk_t
chk
;
if
(
!
p_chk
)
{
if
(
!
AVI_ChunkReadCommon
(
p_input
,
&
chk
)
)
{
return
(
0
);
}
p_chk
=
&
chk
;
}
if
(
p_chk
->
common
.
p_father
)
{
if
(
p_chk
->
common
.
p_father
->
common
.
i_chunk_pos
+
__EVEN
(
p_chk
->
common
.
p_father
->
common
.
i_chunk_size
)
+
8
<
p_chk
->
common
.
i_chunk_pos
+
__EVEN
(
p_chk
->
common
.
i_chunk_size
)
+
8
)
{
return
(
0
);
}
}
return
(
AVI_SeekAbsolute
(
p_input
,
p_chk
->
common
.
i_chunk_pos
+
__EVEN
(
p_chk
->
common
.
i_chunk_size
)
+
8
)
);
}
int
_AVI_ChunkGoto
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
if
(
!
p_chk
)
{
return
(
0
);
}
return
(
AVI_SeekAbsolute
(
p_input
,
p_chk
->
common
.
i_chunk_pos
)
);
}
/****************************************************************************
*
* Functions to read chunks
*
****************************************************************************/
static
int
AVI_ChunkRead_list
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_container
,
int
b_seekable
)
{
avi_chunk_t
*
p_chk
;
u8
*
p_peek
;
if
(
p_container
->
common
.
i_chunk_size
<
8
)
{
/* empty box */
msg_Warn
(
p_input
,
"empty list chunk"
);
return
(
0
);
}
if
(
input_Peek
(
p_input
,
&
p_peek
,
12
)
<
12
)
{
msg_Warn
(
p_input
,
"cannot peek while reading list chunk"
);
return
(
0
);
}
p_container
->
list
.
i_type
=
GetDWLE
(
p_peek
+
8
);
if
(
p_container
->
common
.
i_chunk_fourcc
==
AVIFOURCC_LIST
&&
p_container
->
list
.
i_type
==
AVIFOURCC_movi
)
{
msg_Dbg
(
p_input
,
"Skipping movi chunk"
);
if
(
b_seekable
)
{
return
(
AVI_NextChunk
(
p_input
,
p_container
)
);
}
else
{
return
(
1
);
// point at begining of LIST-movi
}
}
AVI_SkipBytes
(
p_input
,
12
);
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"found LIST chunk:
\'
%c%c%c%c
\'
"
,
AVIFOURCC_PRINT
(
p_container
->
list
.
i_type
)
);
#endif
for
(
;
;
)
{
p_chk
=
malloc
(
sizeof
(
avi_chunk_t
)
);
memset
(
p_chk
,
0
,
sizeof
(
avi_chunk_t
)
);
if
(
!
p_container
->
common
.
p_first
)
{
p_container
->
common
.
p_first
=
p_chk
;
}
else
{
p_container
->
common
.
p_last
->
common
.
p_next
=
p_chk
;
}
p_container
->
common
.
p_last
=
p_chk
;
if
(
!
AVI_ChunkRead
(
p_input
,
p_chk
,
p_container
,
b_seekable
)
||
(
AVI_TellAbsolute
(
p_input
)
>=
p_chk
->
common
.
p_father
->
common
.
i_chunk_pos
+
__EVEN
(
p_chk
->
common
.
p_father
->
common
.
i_chunk_size
)
)
)
{
break
;
}
/* If we can't seek then stop when we 've found LIST-movi */
if
(
p_chk
->
common
.
i_chunk_fourcc
==
AVIFOURCC_LIST
&&
p_chk
->
list
.
i_type
==
AVIFOURCC_movi
&&
!
b_seekable
)
{
break
;
}
}
return
(
1
);
}
#define AVI_READCHUNK_ENTER \
s64 i_read = __EVEN(p_chk->common.i_chunk_size ) + 8; \
u8 *p_read, *p_buff; \
if( !( p_read = p_buff = malloc(i_read ) ) ) \
{ \
return( 0 ); \
} \
i_read = AVI_ReadData( p_input, p_read, i_read ); \
p_read += 8; \
i_read -= 8
#define AVI_READCHUNK_EXIT( code ) \
free( p_buff ); \
if( i_read < 0 ) \
{ \
msg_Warn( p_input, "not enougth data" ); \
} \
return( code )
#define AVI_READ2BYTES( i_word ) \
i_word = GetWLE( p_read ); \
p_read += 2; \
i_read -= 2
#define AVI_READ4BYTES( i_dword ) \
i_dword = GetDWLE( p_read ); \
p_read += 4; \
i_read -= 4
#define AVI_READFOURCC( i_dword ) \
i_dword = GetFOURCC( p_read ); \
p_read += 4; \
i_read -= 4
static
int
AVI_ChunkRead_avih
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
AVI_READCHUNK_ENTER
;
AVI_READ4BYTES
(
p_chk
->
avih
.
i_microsecperframe
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_maxbytespersec
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_reserved1
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_flags
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_totalframes
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_initialframes
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_streams
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_suggestedbuffersize
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_width
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_height
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_scale
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_rate
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_start
);
AVI_READ4BYTES
(
p_chk
->
avih
.
i_length
);
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"avih: streams:%d flags:%s%s%s%s %dx%d"
,
p_chk
->
avih
.
i_streams
,
p_chk
->
avih
.
i_flags
&
AVIF_HASINDEX
?
" HAS_INDEX"
:
""
,
p_chk
->
avih
.
i_flags
&
AVIF_MUSTUSEINDEX
?
" MUST_USE_INDEX"
:
""
,
p_chk
->
avih
.
i_flags
&
AVIF_ISINTERLEAVED
?
" IS_INTERLEAVED"
:
""
,
p_chk
->
avih
.
i_flags
&
AVIF_TRUSTCKTYPE
?
" TRUST_CKTYPE"
:
""
,
p_chk
->
avih
.
i_width
,
p_chk
->
avih
.
i_height
);
#endif
AVI_READCHUNK_EXIT
(
1
);
}
static
int
AVI_ChunkRead_strh
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
AVI_READCHUNK_ENTER
;
AVI_READFOURCC
(
p_chk
->
strh
.
i_type
);
AVI_READFOURCC
(
p_chk
->
strh
.
i_handler
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_flags
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_reserved1
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_initialframes
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_scale
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_rate
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_start
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_length
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_suggestedbuffersize
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_quality
);
AVI_READ4BYTES
(
p_chk
->
strh
.
i_samplesize
);
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"strh: type:%c%c%c%c handler:0x%8.8x samplesize:%d %.2ffps"
,
AVIFOURCC_PRINT
(
p_chk
->
strh
.
i_type
),
p_chk
->
strh
.
i_handler
,
p_chk
->
strh
.
i_samplesize
,
(
p_chk
->
strh
.
i_scale
?
(
float
)
p_chk
->
strh
.
i_rate
/
(
float
)
p_chk
->
strh
.
i_scale
:
-
1
)
);
#endif
AVI_READCHUNK_EXIT
(
1
);
}
static
int
AVI_ChunkRead_strf
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
avi_chunk_t
*
p_strh
;
AVI_READCHUNK_ENTER
;
if
(
p_chk
->
common
.
p_father
==
NULL
)
{
msg_Err
(
p_input
,
"malformed avi file"
);
AVI_READCHUNK_EXIT
(
0
);
}
if
(
!
(
p_strh
=
AVI_ChunkFind
(
p_chk
->
common
.
p_father
,
AVIFOURCC_strh
,
0
)
)
)
{
msg_Err
(
p_input
,
"malformed avi file"
);
AVI_READCHUNK_EXIT
(
0
);
}
switch
(
p_strh
->
strh
.
i_type
)
{
case
(
AVIFOURCC_auds
):
AVI_READ2BYTES
(
p_chk
->
strf
.
auds
.
i_formattag
);
AVI_READ2BYTES
(
p_chk
->
strf
.
auds
.
i_channels
);
AVI_READ4BYTES
(
p_chk
->
strf
.
auds
.
i_samplespersec
);
AVI_READ4BYTES
(
p_chk
->
strf
.
auds
.
i_avgbytespersec
);
AVI_READ2BYTES
(
p_chk
->
strf
.
auds
.
i_blockalign
);
AVI_READ2BYTES
(
p_chk
->
strf
.
auds
.
i_bitspersample
);
if
(
p_chk
->
strf
.
auds
.
i_formattag
!=
WAVE_FORMAT_PCM
)
{
AVI_READ2BYTES
(
p_chk
->
strf
.
auds
.
i_size
);
}
p_chk
->
strf
.
auds
.
p_wfx
=
malloc
(
p_chk
->
common
.
i_chunk_size
);
memcpy
(
p_chk
->
strf
.
auds
.
p_wfx
,
p_buff
+
8
,
p_chk
->
common
.
i_chunk_size
);
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"strf: audio:0x%4.4x channels:%d %dHz %dbits/sample %dkb/s"
,
p_chk
->
strf
.
auds
.
i_formattag
,
p_chk
->
strf
.
auds
.
i_channels
,
p_chk
->
strf
.
auds
.
i_samplespersec
,
p_chk
->
strf
.
auds
.
i_bitspersample
,
p_chk
->
strf
.
auds
.
i_avgbytespersec
*
8
/
1024
);
#endif
break
;
case
(
AVIFOURCC_vids
):
p_strh
->
strh
.
i_samplesize
=
0
;
// XXX for ffmpeg avi file
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_size
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_width
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_height
);
AVI_READ2BYTES
(
p_chk
->
strf
.
vids
.
i_planes
);
AVI_READ2BYTES
(
p_chk
->
strf
.
vids
.
i_bitcount
);
AVI_READFOURCC
(
p_chk
->
strf
.
vids
.
i_compression
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_sizeimage
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_xpelspermeter
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_ypelspermeter
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_clrused
);
AVI_READ4BYTES
(
p_chk
->
strf
.
vids
.
i_clrimportant
);
p_chk
->
strf
.
vids
.
p_bih
=
malloc
(
p_chk
->
common
.
i_chunk_size
);
memcpy
(
p_chk
->
strf
.
vids
.
p_bih
,
p_buff
+
8
,
p_chk
->
common
.
i_chunk_size
);
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"strf: video:%c%c%c%c %dx%d planes:%d %dbpp"
,
AVIFOURCC_PRINT
(
p_chk
->
strf
.
vids
.
i_compression
),
p_chk
->
strf
.
vids
.
i_width
,
p_chk
->
strf
.
vids
.
i_height
,
p_chk
->
strf
.
vids
.
i_planes
,
p_chk
->
strf
.
vids
.
i_bitcount
);
#endif
break
;
default:
msg_Warn
(
p_input
,
"unknown stream type"
);
break
;
}
AVI_READCHUNK_EXIT
(
1
);
}
static
void
AVI_ChunkFree_strf
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
}
static
int
AVI_ChunkRead_strd
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
AVI_READCHUNK_ENTER
;
p_chk
->
strd
.
p_data
=
malloc
(
p_chk
->
common
.
i_chunk_size
);
memcpy
(
p_chk
->
strd
.
p_data
,
p_buff
,
p_chk
->
common
.
i_chunk_size
);
AVI_READCHUNK_EXIT
(
1
);
}
static
int
AVI_ChunkRead_idx1
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
int
i_count
,
i_index
;
AVI_READCHUNK_ENTER
;
i_count
=
__MIN
(
p_chk
->
common
.
i_chunk_size
,
i_read
)
/
16
;
p_chk
->
idx1
.
i_entry_count
=
i_count
;
p_chk
->
idx1
.
i_entry_max
=
i_count
;
if
(
i_count
>
0
)
{
p_chk
->
idx1
.
entry
=
calloc
(
i_count
,
sizeof
(
idx1_entry_t
)
);
for
(
i_index
=
0
;
i_index
<
i_count
;
i_index
++
)
{
AVI_READ4BYTES
(
p_chk
->
idx1
.
entry
[
i_index
].
i_fourcc
);
AVI_READ4BYTES
(
p_chk
->
idx1
.
entry
[
i_index
].
i_flags
);
AVI_READ4BYTES
(
p_chk
->
idx1
.
entry
[
i_index
].
i_pos
);
AVI_READ4BYTES
(
p_chk
->
idx1
.
entry
[
i_index
].
i_length
);
}
}
else
{
p_chk
->
idx1
.
entry
=
NULL
;
}
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"idx1: index entry:%d"
,
i_count
);
#endif
AVI_READCHUNK_EXIT
(
1
);
}
static
void
AVI_ChunkFree_idx1
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
p_chk
->
idx1
.
i_entry_count
=
0
;
p_chk
->
idx1
.
i_entry_max
=
0
;
FREE
(
p_chk
->
idx1
.
entry
)
}
static
struct
{
u32
i_fourcc
;
char
*
psz_type
;
}
AVI_strz_type
[]
=
{
{
AVIFOURCC_IARL
,
"archive location"
},
{
AVIFOURCC_IART
,
"artist"
},
{
AVIFOURCC_ICMS
,
"commisioned"
},
{
AVIFOURCC_ICMT
,
"comments"
},
{
AVIFOURCC_ICOP
,
"copyright"
},
{
AVIFOURCC_ICRD
,
"creation date"
},
{
AVIFOURCC_ICRP
,
"cropped"
},
{
AVIFOURCC_IDIM
,
"dimensions"
},
{
AVIFOURCC_IDPI
,
"dots per inch"
},
{
AVIFOURCC_IENG
,
"enginner"
},
{
AVIFOURCC_IGNR
,
"genre"
},
{
AVIFOURCC_IKEY
,
"keywords"
},
{
AVIFOURCC_ILGT
,
"lightness"
},
{
AVIFOURCC_IMED
,
"medium"
},
{
AVIFOURCC_INAM
,
"name"
},
{
AVIFOURCC_IPLT
,
"palette setting"
},
{
AVIFOURCC_IPRD
,
"product"
},
{
AVIFOURCC_ISBJ
,
"subject"
},
{
AVIFOURCC_ISFT
,
"software"
},
{
AVIFOURCC_ISHP
,
"sharpness"
},
{
AVIFOURCC_ISRC
,
"source"
},
{
AVIFOURCC_ISRF
,
"source form"
},
{
AVIFOURCC_ITCH
,
"technician"
},
{
AVIFOURCC_ISMP
,
"time code"
},
{
AVIFOURCC_IDIT
,
"digitalization time"
},
{
0
,
"???"
}
};
static
int
AVI_ChunkRead_strz
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
int
i_index
;
avi_chunk_STRING_t
*
p_strz
=
(
avi_chunk_STRING_t
*
)
p_chk
;
AVI_READCHUNK_ENTER
;
for
(
i_index
=
0
;;
i_index
++
)
{
if
(
!
AVI_strz_type
[
i_index
].
i_fourcc
||
AVI_strz_type
[
i_index
].
i_fourcc
==
p_strz
->
i_chunk_fourcc
)
{
break
;
}
}
p_strz
->
p_type
=
strdup
(
AVI_strz_type
[
i_index
].
psz_type
);
p_strz
->
p_str
=
malloc
(
i_read
+
1
);
if
(
p_strz
->
i_chunk_size
)
{
memcpy
(
p_strz
->
p_str
,
p_read
,
i_read
);
}
p_strz
->
p_str
[
i_read
]
=
0
;
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"%c%c%c%c: %s : %s"
,
AVIFOURCC_PRINT
(
p_strz
->
i_chunk_fourcc
),
p_strz
->
p_type
,
p_strz
->
p_str
);
#endif
AVI_READCHUNK_EXIT
(
1
);
}
static
void
AVI_ChunkFree_strz
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
avi_chunk_STRING_t
*
p_strz
=
(
avi_chunk_STRING_t
*
)
p_chk
;
FREE
(
p_strz
->
p_type
);
FREE
(
p_strz
->
p_str
);
}
static
int
AVI_ChunkRead_nothing
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
)
{
return
(
AVI_NextChunk
(
p_input
,
p_chk
)
);
}
static
void
AVI_ChunkFree_nothing
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
}
static
struct
{
u32
i_fourcc
;
int
(
*
AVI_ChunkRead_function
)(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
b_seekable
);
void
(
*
AVI_ChunkFree_function
)(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
);
}
AVI_Chunk_Function
[]
=
{
{
AVIFOURCC_RIFF
,
AVI_ChunkRead_list
,
AVI_ChunkFree_nothing
},
{
AVIFOURCC_LIST
,
AVI_ChunkRead_list
,
AVI_ChunkFree_nothing
},
{
AVIFOURCC_avih
,
AVI_ChunkRead_avih
,
AVI_ChunkFree_nothing
},
{
AVIFOURCC_strh
,
AVI_ChunkRead_strh
,
AVI_ChunkFree_nothing
},
{
AVIFOURCC_strf
,
AVI_ChunkRead_strf
,
AVI_ChunkFree_strf
},
{
AVIFOURCC_strd
,
AVI_ChunkRead_strd
,
AVI_ChunkFree_nothing
},
{
AVIFOURCC_idx1
,
AVI_ChunkRead_idx1
,
AVI_ChunkFree_idx1
},
{
AVIFOURCC_JUNK
,
AVI_ChunkRead_nothing
,
AVI_ChunkFree_nothing
},
{
AVIFOURCC_IARL
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IARL
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IART
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ICMS
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ICMT
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ICOP
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ICRD
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ICRP
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IDIM
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IDPI
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IENG
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IGNR
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IKEY
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ILGT
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IMED
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_INAM
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IPLT
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IPRD
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ISBJ
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ISFT
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ISHP
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ISRC
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ISRF
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ITCH
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_ISMP
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
AVIFOURCC_IDIT
,
AVI_ChunkRead_strz
,
AVI_ChunkFree_strz
},
{
0
,
NULL
,
NULL
}
};
static
int
AVI_ChunkFunctionFind
(
int
i_fourcc
)
{
int
i_index
;
for
(
i_index
=
0
;
;
i_index
++
)
{
if
(
(
AVI_Chunk_Function
[
i_index
].
i_fourcc
==
i_fourcc
)
||
(
AVI_Chunk_Function
[
i_index
].
i_fourcc
==
0
)
)
{
return
(
i_index
);
}
}
}
int
_AVI_ChunkRead
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
avi_chunk_t
*
p_father
,
int
b_seekable
)
{
int
i_index
;
int
i_result
;
if
(
!
p_chk
)
{
return
(
0
);
}
if
(
!
AVI_ChunkReadCommon
(
p_input
,
p_chk
)
)
{
msg_Warn
(
p_input
,
"cannot read one chunk"
);
return
(
0
);
}
p_chk
->
common
.
p_father
=
p_father
;
i_index
=
AVI_ChunkFunctionFind
(
p_chk
->
common
.
i_chunk_fourcc
);
if
(
AVI_Chunk_Function
[
i_index
].
AVI_ChunkRead_function
)
{
i_result
=
AVI_Chunk_Function
[
i_index
].
AVI_ChunkRead_function
(
p_input
,
p_chk
,
b_seekable
);
}
else
{
msg_Warn
(
p_input
,
"unknown chunk (not loaded)"
);
i_result
=
AVI_NextChunk
(
p_input
,
p_chk
);
}
return
(
i_result
);
}
void
_AVI_ChunkFree
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
int
i_index
;
avi_chunk_t
*
p_child
,
*
p_next
;
if
(
!
p_chk
)
{
return
;
}
/* Free all child chunk */
p_child
=
p_chk
->
common
.
p_first
;
while
(
p_child
)
{
p_next
=
p_child
->
common
.
p_next
;
AVI_ChunkFree
(
p_input
,
p_child
);
free
(
p_child
);
p_child
=
p_next
;
}
i_index
=
AVI_ChunkFunctionFind
(
p_chk
->
common
.
i_chunk_fourcc
);
if
(
AVI_Chunk_Function
[
i_index
].
AVI_ChunkFree_function
)
{
#ifdef AVI_DEBUG
msg_Dbg
(
p_input
,
"free chunk %c%c%c%c"
,
AVIFOURCC_PRINT
(
p_chk
->
common
.
i_chunk_fourcc
)
);
#endif
AVI_Chunk_Function
[
i_index
].
AVI_ChunkFree_function
(
p_input
,
p_chk
);
}
else
{
msg_Warn
(
p_input
,
"unknown chunk (not unloaded)"
);
}
p_chk
->
common
.
p_first
=
NULL
;
p_chk
->
common
.
p_last
=
NULL
;
return
;
}
int
AVI_ChunkReadRoot
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_root
,
int
b_seekable
)
{
avi_chunk_list_t
*
p_list
=
(
avi_chunk_list_t
*
)
p_root
;
avi_chunk_t
*
p_chk
;
p_list
->
i_chunk_pos
=
0
;
p_list
->
i_chunk_size
=
p_input
->
stream
.
p_selected_area
->
i_size
;
p_list
->
i_chunk_fourcc
=
AVIFOURCC_LIST
;
p_list
->
p_father
=
NULL
;
p_list
->
p_next
=
NULL
;
p_list
->
p_first
=
NULL
;
p_list
->
p_last
=
NULL
;
p_list
->
i_type
=
MKFOURCC
(
'r'
,
'o'
,
'o'
,
't'
);
for
(
;
;
)
{
p_chk
=
malloc
(
sizeof
(
avi_chunk_t
)
);
memset
(
p_chk
,
0
,
sizeof
(
avi_chunk_t
)
);
if
(
!
p_root
->
common
.
p_first
)
{
p_root
->
common
.
p_first
=
p_chk
;
}
else
{
p_root
->
common
.
p_last
->
common
.
p_next
=
p_chk
;
}
p_root
->
common
.
p_last
=
p_chk
;
if
(
!
AVI_ChunkRead
(
p_input
,
p_chk
,
p_root
,
b_seekable
)
||
(
AVI_TellAbsolute
(
p_input
)
>=
p_chk
->
common
.
p_father
->
common
.
i_chunk_pos
+
__EVEN
(
p_chk
->
common
.
p_father
->
common
.
i_chunk_size
)
)
)
{
break
;
}
/* If we can't seek then stop when we 've found first RIFF-AVI */
if
(
p_chk
->
common
.
i_chunk_fourcc
==
AVIFOURCC_RIFF
&&
p_chk
->
list
.
i_type
==
AVIFOURCC_AVI
&&
!
b_seekable
)
{
break
;
}
}
return
(
1
);
}
void
AVI_ChunkFreeRoot
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
AVI_ChunkFree
(
p_input
,
p_chk
);
}
int
_AVI_ChunkCount
(
avi_chunk_t
*
p_chk
,
u32
i_fourcc
)
{
int
i_count
;
avi_chunk_t
*
p_child
;
if
(
!
p_chk
)
{
return
(
0
);
}
i_count
=
0
;
p_child
=
p_chk
->
common
.
p_first
;
while
(
p_child
)
{
if
(
p_child
->
common
.
i_chunk_fourcc
==
i_fourcc
||
(
p_child
->
common
.
i_chunk_fourcc
==
AVIFOURCC_LIST
&&
p_child
->
list
.
i_type
==
i_fourcc
)
)
{
i_count
++
;
}
p_child
=
p_child
->
common
.
p_next
;
}
return
(
i_count
);
}
avi_chunk_t
*
_AVI_ChunkFind
(
avi_chunk_t
*
p_chk
,
u32
i_fourcc
,
int
i_number
)
{
avi_chunk_t
*
p_child
;
if
(
!
p_chk
)
{
return
(
NULL
);
}
p_child
=
p_chk
->
common
.
p_first
;
while
(
p_child
)
{
if
(
p_child
->
common
.
i_chunk_fourcc
==
i_fourcc
||
(
p_child
->
common
.
i_chunk_fourcc
==
AVIFOURCC_LIST
&&
p_child
->
list
.
i_type
==
i_fourcc
)
)
{
if
(
i_number
==
0
)
{
/* We found it */
return
(
p_child
);
}
i_number
--
;
}
p_child
=
p_child
->
common
.
p_next
;
}
return
(
NULL
);
}
static
void
AVI_ChunkDumpDebug_level
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
int
i_level
)
{
char
str
[
1024
];
int
i
;
avi_chunk_t
*
p_child
;
memset
(
str
,
' '
,
sizeof
(
str
)
);
for
(
i
=
1
;
i
<
i_level
;
i
++
)
{
str
[
i
*
5
]
=
'|'
;
}
if
(
p_chk
->
common
.
i_chunk_fourcc
==
AVIFOURCC_RIFF
||
p_chk
->
common
.
i_chunk_fourcc
==
AVIFOURCC_LIST
)
{
sprintf
(
str
+
i_level
*
5
,
"%c %c%c%c%c-%c%c%c%c size:%lld pos:%lld"
,
i_level
?
'+'
:
'*'
,
AVIFOURCC_PRINT
(
p_chk
->
common
.
i_chunk_fourcc
),
AVIFOURCC_PRINT
(
p_chk
->
list
.
i_type
),
p_chk
->
common
.
i_chunk_size
,
p_chk
->
common
.
i_chunk_pos
);
}
else
{
sprintf
(
str
+
i_level
*
5
,
"+ %c%c%c%c size:%lld pos:%lld"
,
AVIFOURCC_PRINT
(
p_chk
->
common
.
i_chunk_fourcc
),
p_chk
->
common
.
i_chunk_size
,
p_chk
->
common
.
i_chunk_pos
);
}
msg_Dbg
(
p_input
,
"%s"
,
str
);
p_child
=
p_chk
->
common
.
p_first
;
while
(
p_child
)
{
AVI_ChunkDumpDebug_level
(
p_input
,
p_child
,
i_level
+
1
);
p_child
=
p_child
->
common
.
p_next
;
}
}
void
_AVI_ChunkDumpDebug
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
)
{
AVI_ChunkDumpDebug_level
(
p_input
,
p_chk
,
0
);
}
modules/demux/avi/libavi.h
0 → 100644
View file @
706297b3
/*****************************************************************************
* libavi.h : LibAVI library
******************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libavi.h,v 1.1 2002/10/15 00:56:43 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.
*****************************************************************************/
/* flags for use in <dwFlags> in AVIFileHdr */
#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 */
#define AVIIF_FIXKEYFRAME 0x00001000L
/* invented; used to say that
the keyframe flag isn't a true flag
but have to be verified */
#define MKFOURCC( a, b, c, d ) \
( ((u32)a) | ( ((u32)b) << 8 ) | ( ((u32)c) << 16 ) | ( ((u32)d) << 24 ) )
#define MKTWOCC( a, b ) \
( (u16)(a) | ( (u16)(b) << 8 ) )
/* *** avi stuff *** */
#define AVIFOURCC_RIFF MKFOURCC('R','I','F','F')
#define AVIFOURCC_LIST MKFOURCC('L','I','S','T')
#define AVIFOURCC_JUNK MKFOURCC('J','U','N','K')
#define AVIFOURCC_AVI MKFOURCC('A','V','I',' ')
#define AVIFOURCC_WAVE MKFOURCC('W','A','V','E')
#define AVIFOURCC_INFO MKFOURCC('I','N','F','O')
#define AVIFOURCC_avih MKFOURCC('a','v','i','h')
#define AVIFOURCC_hdrl MKFOURCC('h','d','r','l')
#define AVIFOURCC_movi MKFOURCC('m','o','v','i')
#define AVIFOURCC_idx1 MKFOURCC('i','d','x','1')
#define AVIFOURCC_strl MKFOURCC('s','t','r','l')
#define AVIFOURCC_strh MKFOURCC('s','t','r','h')
#define AVIFOURCC_strf MKFOURCC('s','t','r','f')
#define AVIFOURCC_strd MKFOURCC('s','t','r','d')
#define AVIFOURCC_rec MKFOURCC('r','e','c',' ')
#define AVIFOURCC_auds MKFOURCC('a','u','d','s')
#define AVIFOURCC_vids MKFOURCC('v','i','d','s')
#define AVIFOURCC_IARL MKFOURCC('I','A','R','L')
#define AVIFOURCC_IART MKFOURCC('I','A','R','T')
#define AVIFOURCC_ICMS MKFOURCC('I','C','M','S')
#define AVIFOURCC_ICMT MKFOURCC('I','C','M','T')
#define AVIFOURCC_ICOP MKFOURCC('I','C','O','P')
#define AVIFOURCC_ICRD MKFOURCC('I','C','R','D')
#define AVIFOURCC_ICRP MKFOURCC('I','C','R','P')
#define AVIFOURCC_IDIM MKFOURCC('I','D','I','M')
#define AVIFOURCC_IDPI MKFOURCC('I','D','P','I')
#define AVIFOURCC_IENG MKFOURCC('I','E','N','G')
#define AVIFOURCC_IGNR MKFOURCC('I','G','N','R')
#define AVIFOURCC_IKEY MKFOURCC('I','K','E','Y')
#define AVIFOURCC_ILGT MKFOURCC('I','L','G','T')
#define AVIFOURCC_IMED MKFOURCC('I','M','E','D')
#define AVIFOURCC_INAM MKFOURCC('I','N','A','M')
#define AVIFOURCC_IPLT MKFOURCC('I','P','L','T')
#define AVIFOURCC_IPRD MKFOURCC('I','P','R','D')
#define AVIFOURCC_ISBJ MKFOURCC('I','S','B','J')
#define AVIFOURCC_ISFT MKFOURCC('I','S','F','T')
#define AVIFOURCC_ISHP MKFOURCC('I','S','H','P')
#define AVIFOURCC_ISRC MKFOURCC('I','S','R','C')
#define AVIFOURCC_ISRF MKFOURCC('I','S','R','F')
#define AVIFOURCC_ITCH MKFOURCC('I','T','C','H')
#define AVIFOURCC_ISMP MKFOURCC('I','S','M','P')
#define AVIFOURCC_IDIT MKFOURCC('I','D','I','T')
#define AVITWOCC_wb MKTWOCC('w','b')
#define AVITWOCC_db MKTWOCC('d','b')
#define AVITWOCC_dc MKTWOCC('d','c')
#define AVITWOCC_pc MKTWOCC('p','c')
/* *** codex stuff *** */
/* MPEG4 video */
#define FOURCC_DIVX VLC_FOURCC('D','I','V','X')
#define FOURCC_divx VLC_FOURCC('d','i','v','x')
#define FOURCC_DIV1 VLC_FOURCC('D','I','V','1')
#define FOURCC_div1 VLC_FOURCC('d','i','v','1')
#define FOURCC_MP4S VLC_FOURCC('M','P','4','S')
#define FOURCC_mp4s VLC_FOURCC('m','p','4','s')
#define FOURCC_M4S2 VLC_FOURCC('M','4','S','2')
#define FOURCC_m4s2 VLC_FOURCC('m','4','s','2')
#define FOURCC_xvid VLC_FOURCC('x','v','i','d')
#define FOURCC_XVID VLC_FOURCC('X','V','I','D')
#define FOURCC_XviD VLC_FOURCC('X','v','i','D')
#define FOURCC_DX50 VLC_FOURCC('D','X','5','0')
#define FOURCC_mp4v VLC_FOURCC('m','p','4','v')
#define FOURCC_4 VLC_FOURCC( 4, 0, 0, 0 )
/* MSMPEG4 v2 */
#define FOURCC_MPG4 VLC_FOURCC('M','P','G','4')
#define FOURCC_mpg4 VLC_FOURCC('m','p','g','4')
#define FOURCC_DIV2 VLC_FOURCC('D','I','V','2')
#define FOURCC_div2 VLC_FOURCC('d','i','v','2')
#define FOURCC_MP42 VLC_FOURCC('M','P','4','2')
#define FOURCC_mp42 VLC_FOURCC('m','p','4','2')
/* MSMPEG4 v3 / M$ mpeg4 v3 */
#define FOURCC_MPG3 VLC_FOURCC('M','P','G','3')
#define FOURCC_mpg3 VLC_FOURCC('m','p','g','3')
#define FOURCC_div3 VLC_FOURCC('d','i','v','3')
#define FOURCC_MP43 VLC_FOURCC('M','P','4','3')
#define FOURCC_mp43 VLC_FOURCC('m','p','4','3')
/* DivX 3.20 */
#define FOURCC_DIV3 VLC_FOURCC('D','I','V','3')
#define FOURCC_DIV4 VLC_FOURCC('D','I','V','4')
#define FOURCC_div4 VLC_FOURCC('d','i','v','4')
#define FOURCC_DIV5 VLC_FOURCC('D','I','V','5')
#define FOURCC_div5 VLC_FOURCC('d','i','v','5')
#define FOURCC_DIV6 VLC_FOURCC('D','I','V','6')
#define FOURCC_div6 VLC_FOURCC('d','i','v','6')
/* AngelPotion stuff */
#define FOURCC_AP41 VLC_FOURCC('A','P','4','1')
/* ?? */
#define FOURCC_3IV1 VLC_FOURCC('3','I','V','1')
/* H263 and H263i */
#define FOURCC_H263 VLC_FOURCC('H','2','6','3')
#define FOURCC_h263 VLC_FOURCC('h','2','6','3')
#define FOURCC_U263 VLC_FOURCC('U','2','6','3')
#define FOURCC_I263 VLC_FOURCC('I','2','6','3')
#define FOURCC_i263 VLC_FOURCC('i','2','6','3')
/* Sound formats */
#define WAVE_FORMAT_UNKNOWN 0x0000
#define WAVE_FORMAT_PCM 0x0001
#define WAVE_FORMAT_MPEG 0x0050
#define WAVE_FORMAT_MPEGLAYER3 0x0055
#define WAVE_FORMAT_A52 0x2000
#define WAVE_FORMAT_WMA1 0x0160
#define WAVE_FORMAT_WMA2 0x0161
#define AVI_CHUNK_COMMON \
u32 i_chunk_fourcc; \
u64 i_chunk_size; \
u64 i_chunk_pos; \
union avi_chunk_u *p_next; \
union avi_chunk_u *p_father; \
union avi_chunk_u *p_first; \
union avi_chunk_u *p_last;
#define AVI_CHUNK( p_chk ) (avi_chunk_t*)(p_chk)
typedef
struct
idx1_entry_s
{
vlc_fourcc_t
i_fourcc
;
u32
i_flags
;
u32
i_pos
;
u32
i_length
;
}
idx1_entry_t
;
typedef
struct
avi_chunk_common_s
{
AVI_CHUNK_COMMON
}
avi_chunk_common_t
;
typedef
struct
avi_chunk_list_s
{
AVI_CHUNK_COMMON
u32
i_type
;
}
avi_chunk_list_t
;
typedef
struct
avi_chunk_idx1_s
{
AVI_CHUNK_COMMON
int
i_entry_count
;
int
i_entry_max
;
idx1_entry_t
*
entry
;
}
avi_chunk_idx1_t
;
typedef
struct
avi_chunk_avih_s
{
AVI_CHUNK_COMMON
u32
i_microsecperframe
;
u32
i_maxbytespersec
;
u32
i_reserved1
;
/* dwPaddingGranularity; pad to multiples of this
size; normally 2K */
u32
i_flags
;
u32
i_totalframes
;
u32
i_initialframes
;
u32
i_streams
;
u32
i_suggestedbuffersize
;
u32
i_width
;
u32
i_height
;
u32
i_scale
;
u32
i_rate
;
u32
i_start
;
u32
i_length
;
}
avi_chunk_avih_t
;
typedef
struct
avi_chunk_strh_s
{
AVI_CHUNK_COMMON
u32
i_type
;
u32
i_handler
;
u32
i_flags
;
u32
i_reserved1
;
/* wPriority wLanguage */
u32
i_initialframes
;
u32
i_scale
;
u32
i_rate
;
u32
i_start
;
u32
i_length
;
/* In units above... */
u32
i_suggestedbuffersize
;
u32
i_quality
;
u32
i_samplesize
;
}
avi_chunk_strh_t
;
typedef
struct
avi_chunk_strf_auds_s
{
AVI_CHUNK_COMMON
void
*
p_wfx
;
// waveformatex_t loaded from file
u16
i_formattag
;
// + 0x00
u16
i_channels
;
// + 0x02
u32
i_samplespersec
;
// + 0x04
u32
i_avgbytespersec
;
// + 0x08
u16
i_blockalign
;
// + 0x0c
u16
i_bitspersample
;
// + 0x0e
u16
i_size
;
/* the extra size in bytes */
u8
*
p_data
;
}
avi_chunk_strf_auds_t
;
typedef
struct
avi_chunk_strf_vids_s
{
AVI_CHUNK_COMMON
void
*
p_bih
;
// bitmapinfoheader_t loaded from file
u32
i_size
;
/* size of header */
u32
i_width
;
u32
i_height
;
u16
i_planes
;
u16
i_bitcount
;
u32
i_compression
;
u32
i_sizeimage
;
u32
i_xpelspermeter
;
u32
i_ypelspermeter
;
u32
i_clrused
;
u32
i_clrimportant
;
}
avi_chunk_strf_vids_t
;
typedef
union
avi_chunk_strf_u
{
avi_chunk_strf_auds_t
auds
;
avi_chunk_strf_vids_t
vids
;
}
avi_chunk_strf_t
;
typedef
struct
avi_chunk_strd_s
{
AVI_CHUNK_COMMON
u8
*
p_data
;
}
avi_chunk_strd_t
;
typedef
struct
avi_chunk_STRING_s
{
AVI_CHUNK_COMMON
char
*
p_type
;
char
*
p_str
;
}
avi_chunk_STRING_t
;
typedef
union
avi_chunk_u
{
avi_chunk_common_t
common
;
avi_chunk_list_t
list
;
avi_chunk_idx1_t
idx1
;
avi_chunk_avih_t
avih
;
avi_chunk_strh_t
strh
;
avi_chunk_strf_t
strf
;
avi_chunk_strd_t
strd
;
avi_chunk_STRING_t
strz
;
}
avi_chunk_t
;
/****************************************************************************
* AVI_TestFile : test file header to see if it's an avi file
****************************************************************************/
int
AVI_TestFile
(
input_thread_t
*
p_input
);
/****************************************************************************
* Stream(input) acces function
****************************************************************************/
off_t
AVI_TellAbsolute
(
input_thread_t
*
p_input
);
int
AVI_SeekAbsolute
(
input_thread_t
*
p_input
,
off_t
i_pos
);
int
AVI_ReadData
(
input_thread_t
*
p_input
,
u8
*
p_buff
,
int
i_size
);
int
AVI_SkipBytes
(
input_thread_t
*
p_input
,
int
i_count
);
int
_AVI_ChunkRead
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
,
avi_chunk_t
*
p_father
,
int
b_seekable
);
void
_AVI_ChunkFree
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
);
int
_AVI_ChunkGoto
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
);
void
_AVI_ChunkDumpDebug
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
);
int
_AVI_ChunkCount
(
avi_chunk_t
*
p_chk
,
u32
i_fourcc
);
avi_chunk_t
*
_AVI_ChunkFind
(
avi_chunk_t
*
p_chk
,
u32
i_fourcc
,
int
i_number
);
int
AVI_ChunkReadRoot
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_root
,
int
b_seekable
);
void
AVI_ChunkFreeRoot
(
input_thread_t
*
p_input
,
avi_chunk_t
*
p_chk
);
#define AVI_ChunkRead( p_input, p_chk, p_father, b_seekable ) \
_AVI_ChunkRead( p_input, \
(avi_chunk_t*)p_chk, \
(avi_chunk_t*)p_father, \
b_seekable )
#define AVI_ChunkFree( p_input, p_chk ) \
_AVI_ChunkFree( p_input, (avi_chunk_t*)p_chk )
#define AVI_ChunkGoto( p_input, p_chk ) \
_AVI_ChunkGoto( p_input, (avi_chunk_t*)p_chk )
#define AVI_ChunkDumpDebug( p_input, p_chk ) \
_AVI_ChunkDumpDebug( p_input, (avi_chunk_t*)p_chk )
#define AVI_ChunkCount( p_chk, i_fourcc ) \
_AVI_ChunkCount( (avi_chunk_t*)p_chk, i_fourcc )
#define AVI_ChunkFind( p_chk, i_fourcc, i_number ) \
_AVI_ChunkFind( (avi_chunk_t*)p_chk, i_fourcc, i_number )
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