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
651d773d
Commit
651d773d
authored
Mar 09, 2005
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle VOC files with multiple blocks properly
parent
2c53152a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
118 additions
and
70 deletions
+118
-70
modules/demux/voc.c
modules/demux/voc.c
+118
-70
No files found.
modules/demux/voc.c
View file @
651d773d
...
...
@@ -2,7 +2,7 @@
* voc.c : Creative Voice File (.VOC) demux module for vlc
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id
: xa.c 10182 2005-03-07 15:04:53Z courmisch
$
* $Id$
*
* Authors: Remi Denis-Courmont <rem # via.ecp.fr>
*
...
...
@@ -72,7 +72,7 @@ static int Open( vlc_object_t * p_this )
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
uint8_t
*
p_buf
,
buf
[
8
]
;
uint8_t
*
p_buf
;
uint16_t
i_data_offset
,
i_version
;
if
(
stream_Peek
(
p_demux
->
s
,
&
p_buf
,
26
)
<
26
)
...
...
@@ -103,137 +103,187 @@ static int Open( vlc_object_t * p_this )
if
(
stream_Read
(
p_demux
->
s
,
NULL
,
i_data_offset
)
<
i_data_offset
)
return
VLC_EGENERIC
;
/* read first block header */
/* FIXME: we only support one-block files at the moment */
if
(
stream_Read
(
p_demux
->
s
,
buf
,
4
)
<
4
)
return
VLC_EGENERIC
;
p_demux
->
pf_demux
=
Demux
;
p_demux
->
pf_control
=
Control
;
p_demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_sys
->
i_block_size
=
GetDWLE
(
buf
)
>>
8
;
msg_Dbg
(
p_demux
,
"block size: %u bytes"
,
p_sys
->
i_block_size
);
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
p_sys
->
i_block_offset
=
p_sys
->
i_block_size
=
0
;
p_sys
->
p_es
=
NULL
;
date_Init
(
&
p_sys
->
pts
,
1
,
1
);
date_Set
(
&
p_sys
->
pts
,
1
);
return
VLC_SUCCESS
;
}
static
int
fmtcmp
(
es_format_t
*
ofmt
,
es_format_t
*
nfmt
)
{
return
(
ofmt
->
audio
.
i_bitspersample
!=
nfmt
->
audio
.
i_bitspersample
)
||
(
ofmt
->
audio
.
i_rate
!=
nfmt
->
audio
.
i_rate
)
||
(
ofmt
->
audio
.
i_channels
!=
nfmt
->
audio
.
i_channels
);
}
static
int
ReadBlockHeader
(
demux_t
*
p_demux
)
{
es_format_t
new_fmt
;
uint8_t
buf
[
8
];
int32_t
i_block_size
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
stream_Read
(
p_demux
->
s
,
buf
,
4
)
<
4
)
return
VLC_EGENERIC
;
/* EOF */
i_block_size
=
GetDWLE
(
buf
)
>>
8
;
msg_Dbg
(
p_demux
,
"new block: type: %u, size: %u"
,
(
unsigned
)
*
buf
,
i_block_size
);
es_format_Init
(
&
p_sys
->
fmt
,
AUDIO_ES
,
0
);
es_format_Init
(
&
new_
fmt
,
AUDIO_ES
,
0
);
switch
(
*
buf
)
{
/*case 0: -- not possible caught earlier with stream_Read */
case
1
:
if
(
p_sys
->
i_block_size
<
2
)
goto
error
;
p_sys
->
i_block_size
-=
2
;
if
(
i_block_size
<
2
)
return
VLC_EGENERIC
;
i_block_size
-=
2
;
if
(
stream_Read
(
p_demux
->
s
,
buf
,
2
)
<
2
)
goto
error
;
return
VLC_EGENERIC
;
p_sys
->
fmt
.
audio
.
i_rate
=
1000000L
/
(
256L
-
buf
[
0
]);
new_
fmt
.
audio
.
i_rate
=
1000000L
/
(
256L
-
buf
[
0
]);
if
(
buf
[
1
]
)
{
msg_Err
(
p_demux
,
"Unsupported compression"
);
goto
error
;
return
VLC_EGENERIC
;
}
p_sys
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'8'
,
' '
,
' '
);
p_sys
->
fmt
.
audio
.
i_bytes_per_frame
=
1
;
p_sys
->
fmt
.
audio
.
i_frame_length
=
1
;
p_sys
->
fmt
.
audio
.
i_channels
=
1
;
p_sys
->
fmt
.
audio
.
i_blockalign
=
1
;
p_sys
->
fmt
.
audio
.
i_bitspersample
=
8
;
p_sys
->
fmt
.
i_bitrate
=
p_sys
->
fmt
.
audio
.
i_rate
*
8
;
new_fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'8'
,
' '
,
' '
);
new_fmt
.
audio
.
i_bytes_per_frame
=
1
;
new_fmt
.
audio
.
i_frame_length
=
1
;
new_fmt
.
audio
.
i_channels
=
1
;
new_fmt
.
audio
.
i_blockalign
=
1
;
new_fmt
.
audio
.
i_bitspersample
=
8
;
new_fmt
.
i_bitrate
=
p_sys
->
fmt
.
audio
.
i_rate
*
8
;
break
;
/* FIXME: support block types 2, 3, 6, 7, 8 properly */
case
2
:
case
3
:
case
6
:
case
7
:
case
8
:
/* non-audio block types can be skipped */
case
4
:
case
5
:
if
(
stream_Read
(
p_demux
->
s
,
NULL
,
i_block_size
)
<
i_block_size
)
return
VLC_EGENERIC
;
i_block_size
=
0
;
break
;
case
9
:
if
(
p_sys
->
i_block_size
<
12
)
goto
error
;
p_sys
->
i_block_size
-=
12
;
if
(
i_block_size
<
12
)
return
VLC_EGENERIC
;
i_block_size
-=
12
;
if
(
(
stream_Read
(
p_demux
->
s
,
buf
,
8
)
<
8
)
||
(
stream_Read
(
p_demux
->
s
,
NULL
,
4
)
<
4
)
)
goto
error
;
return
VLC_EGENERIC
;
p_sys
->
fmt
.
audio
.
i_rate
=
GetDWLE
(
buf
);
p_sys
->
fmt
.
audio
.
i_bitspersample
=
buf
[
4
];
p_sys
->
fmt
.
audio
.
i_channels
=
buf
[
5
];
new_
fmt
.
audio
.
i_rate
=
GetDWLE
(
buf
);
new_
fmt
.
audio
.
i_bitspersample
=
buf
[
4
];
new_
fmt
.
audio
.
i_channels
=
buf
[
5
];
switch
(
GetWLE
(
&
buf
[
6
]
)
)
/* format */
{
case
0x0000
:
/* PCM */
switch
(
p_sys
->
fmt
.
audio
.
i_bitspersample
)
switch
(
new_
fmt
.
audio
.
i_bitspersample
)
{
case
8
:
p_sys
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'8'
,
' '
,
' '
);
new_
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'8'
,
' '
,
' '
);
break
;
case
16
:
p_sys
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'1'
,
'6'
,
'l'
);
new_
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'1'
,
'6'
,
'l'
);
break
;
default:
msg_Err
(
p_demux
,
"Unsupported bit res.: %u bits"
,
p_sys
->
fmt
.
audio
.
i_bitspersample
);
new_
fmt
.
audio
.
i_bitspersample
);
return
VLC_EGENERIC
;
}
break
;
case
0x0004
:
/* signed */
switch
(
p_sys
->
fmt
.
audio
.
i_bitspersample
)
switch
(
new_
fmt
.
audio
.
i_bitspersample
)
{
case
8
:
p_sys
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'8'
,
' '
,
' '
);
new_
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'8'
,
' '
,
' '
);
break
;
case
16
:
p_sys
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'1'
,
'6'
,
'l'
);
new_
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'1'
,
'6'
,
'l'
);
break
;
default:
msg_Err
(
p_demux
,
"Unsupported bit res.: %u bits"
,
p_sys
->
fmt
.
audio
.
i_bitspersample
);
new_
fmt
.
audio
.
i_bitspersample
);
return
VLC_EGENERIC
;
}
break
;
default:
msg_Err
(
p_demux
,
"Unsupported compression"
);
goto
error
;
return
VLC_EGENERIC
;
}
p_sys
->
fmt
.
audio
.
i_bytes_per_frame
=
p_sys
->
fmt
.
audio
.
i_channels
*
(
p_sys
->
fmt
.
audio
.
i_bitspersample
/
8
);
p_sys
->
fmt
.
audio
.
i_frame_length
=
1
;
p_sys
->
fmt
.
audio
.
i_blockalign
=
p_sys
->
fmt
.
audio
.
i_bytes_per_frame
;
p_sys
->
fmt
.
i_bitrate
=
8
*
p_sys
->
fmt
.
audio
.
i_rate
*
p_sys
->
fmt
.
audio
.
i_bytes_per_frame
;
new_fmt
.
audio
.
i_bytes_per_frame
=
new_
fmt
.
audio
.
i_channels
*
(
new_
fmt
.
audio
.
i_bitspersample
/
8
);
new_
fmt
.
audio
.
i_frame_length
=
1
;
new_
fmt
.
audio
.
i_blockalign
=
p_sys
->
fmt
.
audio
.
i_bytes_per_frame
;
new_fmt
.
i_bitrate
=
8
*
new_
fmt
.
audio
.
i_rate
*
new_
fmt
.
audio
.
i_bytes_per_frame
;
break
;
default:
msg_Dbg
(
p_demux
,
"Unsupported block type %u"
,
(
unsigned
)
*
p_
buf
);
msg_Dbg
(
p_demux
,
"Unsupported block type %u"
,
(
unsigned
)
*
buf
);
return
VLC_EGENERIC
;
}
p_sys
->
i_block_offset
=
stream_Tell
(
p_demux
->
s
);
p_sys
->
fmt
.
i_extra
=
0
;
p_sys
->
fmt
.
p_extra
=
NULL
;
p_sys
->
i_block_size
=
i_block_size
;
p_sys
->
i_block_offset
=
stream_Tell
(
p_demux
->
s
)
;
if
(
i_block_size
)
{
/* we've read a block with data in it - update decoder */
msg_Dbg
(
p_demux
,
"fourcc: %4.4s, channels: %d, "
"freq: %d Hz, bitrate: %dKo/s, blockalign: %d, bits/samples: %d"
,
(
char
*
)
&
p_sys
->
fmt
.
i_codec
,
p_sys
->
fmt
.
audio
.
i_channels
,
p_sys
->
fmt
.
audio
.
i_rate
,
p_sys
->
fmt
.
i_bitrate
/
8192
,
p_sys
->
fmt
.
audio
.
i_blockalign
,
p_sys
->
fmt
.
audio
.
i_bitspersample
);
"freq: %d Hz, bitrate: %dKo/s, blockalign: %d, "
"bits/samples: %d"
,
(
char
*
)
&
new_fmt
.
i_codec
,
new_fmt
.
audio
.
i_channels
,
new_fmt
.
audio
.
i_rate
,
new_fmt
.
i_bitrate
/
8192
,
new_fmt
.
audio
.
i_blockalign
,
new_fmt
.
audio
.
i_bitspersample
);
p_sys
->
p_es
=
es_out_Add
(
p_demux
->
out
,
&
p_sys
->
fmt
);
if
(
(
p_sys
->
p_es
!=
NULL
)
&&
fmtcmp
(
&
p_sys
->
fmt
,
&
new_fmt
)
)
{
msg_Dbg
(
p_demux
,
"codec change needed"
);
es_out_Del
(
p_demux
->
out
,
p_sys
->
p_es
);
p_sys
->
p_es
=
NULL
;
}
date_Init
(
&
p_sys
->
pts
,
p_sys
->
fmt
.
audio
.
i_rate
,
1
);
date_Set
(
&
p_sys
->
pts
,
1
);
if
(
p_sys
->
p_es
==
NULL
)
{
memcpy
(
&
p_sys
->
fmt
,
&
new_fmt
,
sizeof
(
p_sys
->
fmt
)
);
date_Change
(
&
p_sys
->
pts
,
p_sys
->
fmt
.
audio
.
i_rate
,
1
);
p_sys
->
p_es
=
es_out_Add
(
p_demux
->
out
,
&
p_sys
->
fmt
);
}
}
return
VLC_SUCCESS
;
error:
msg_Err
(
p_demux
,
"Unsupported or malformatted file"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
/*****************************************************************************
...
...
@@ -249,11 +299,9 @@ static int Demux( demux_t *p_demux )
i_offset
=
stream_Tell
(
p_demux
->
s
);
if
(
i_offset
>=
p_sys
->
i_block_offset
+
p_sys
->
i_block_size
)
{
/* EOF */
while
(
i_offset
>=
p_sys
->
i_block_offset
+
p_sys
->
i_block_size
)
if
(
ReadBlockHeader
(
p_demux
)
!=
VLC_SUCCESS
)
return
0
;
}
p_block
=
stream_Block
(
p_demux
->
s
,
p_sys
->
fmt
.
audio
.
i_bytes_per_frame
);
if
(
p_block
==
NULL
)
...
...
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