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
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