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
933abd7b
Commit
933abd7b
authored
Apr 13, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split out a52 parsing functions into a52.h
parent
2479ed41
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
250 additions
and
195 deletions
+250
-195
modules/codec/a52.c
modules/codec/a52.c
+23
-195
modules/codec/a52.h
modules/codec/a52.h
+227
-0
No files found.
modules/codec/a52.c
View file @
933abd7b
This diff is collapsed.
Click to expand it.
modules/codec/a52.h
0 → 100644
View file @
933abd7b
/*****************************************************************************
* a52.h
*****************************************************************************
* Copyright (C) 2001-2009 Laurent Aimar
* $Id$
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org>
* 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _VLC_A52_H
#define _VLC_A52_H 1
#include <vlc_aout.h>
#include <vlc_bits.h>
typedef
struct
{
unsigned
int
i_count
;
unsigned
int
i_configuration
;
}
vlc_a52_acmod_t
;
/**
* Minimum AC3 header size that vlc_a52_header_Parse needs.
*/
#define VLC_A52_HEADER_SIZE (8)
/**
* AC3 header information.
*/
typedef
struct
{
bool
b_eac3
;
unsigned
int
i_channels
;
unsigned
int
i_channels_conf
;
unsigned
int
i_rate
;
unsigned
int
i_bitrate
;
unsigned
int
i_size
;
}
vlc_a52_header_t
;
/**
* It parse AC3 sync info.
*
* This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse,
* since we don't want to oblige S/PDIF people to use liba52 just to get
* their SyncInfo...
*/
static
inline
int
vlc_a52_header_ParseAc3
(
vlc_a52_header_t
*
p_header
,
const
uint8_t
*
p_buf
,
const
vlc_a52_acmod_t
*
p_acmod
)
{
static
const
uint8_t
pi_halfrate
[
12
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
2
,
3
};
static
const
unsigned
int
pi_bitrate
[]
=
{
32
,
40
,
48
,
56
,
64
,
80
,
96
,
112
,
128
,
160
,
192
,
224
,
256
,
320
,
384
,
448
,
512
,
576
,
640
};
static
const
uint8_t
pi_lfeon
[
8
]
=
{
0x10
,
0x10
,
0x04
,
0x04
,
0x04
,
0x01
,
0x04
,
0x01
};
/* */
const
unsigned
i_rate_shift
=
pi_halfrate
[
p_buf
[
5
]
>>
3
];
/* acmod, dsurmod and lfeon */
const
unsigned
i_acmod
=
p_buf
[
6
]
>>
5
;
if
(
(
p_buf
[
6
]
&
0xf8
)
==
0x50
)
{
/* Dolby surround = stereo + Dolby */
p_header
->
i_channels
=
2
;
p_header
->
i_channels_conf
=
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_DOLBYSTEREO
;
}
else
{
p_header
->
i_channels
=
p_acmod
[
i_acmod
].
i_count
;
p_header
->
i_channels_conf
=
p_acmod
[
i_acmod
].
i_configuration
;
}
if
(
p_buf
[
6
]
&
pi_lfeon
[
i_acmod
]
)
{
p_header
->
i_channels
++
;
p_header
->
i_channels_conf
|=
AOUT_CHAN_LFE
;
}
const
unsigned
i_frmsizecod
=
p_buf
[
4
]
&
63
;
if
(
i_frmsizecod
>=
38
)
return
VLC_EGENERIC
;
const
unsigned
i_bitrate_base
=
pi_bitrate
[
i_frmsizecod
>>
1
];
p_header
->
i_bitrate
=
(
i_bitrate_base
*
1000
)
>>
i_rate_shift
;
switch
(
p_buf
[
4
]
&
0xc0
)
{
case
0
:
p_header
->
i_rate
=
48000
>>
i_rate_shift
;
p_header
->
i_size
=
4
*
i_bitrate_base
;
break
;
case
0x40
:
p_header
->
i_rate
=
44100
>>
i_rate_shift
;
p_header
->
i_size
=
2
*
(
320
*
i_bitrate_base
/
147
+
(
i_frmsizecod
&
1
));
break
;
case
0x80
:
p_header
->
i_rate
=
32000
>>
i_rate_shift
;
p_header
->
i_size
=
6
*
i_bitrate_base
;
break
;
default:
return
VLC_EGENERIC
;
}
p_header
->
b_eac3
=
false
;
return
VLC_SUCCESS
;
}
/**
* It parse E-AC3 sync info
*/
static
inline
int
vlc_a52_header_ParseEac3
(
vlc_a52_header_t
*
p_header
,
const
uint8_t
*
p_buf
,
const
vlc_a52_acmod_t
*
p_acmod
)
{
static
const
unsigned
pi_samplerate
[
3
]
=
{
48000
,
44100
,
32000
};
unsigned
i_numblkscod
;
bs_t
s
;
bs_init
(
&
s
,
(
void
*
)
p_buf
,
VLC_A52_HEADER_SIZE
);
bs_skip
(
&
s
,
16
+
/* start code */
2
+
/* stream type */
3
);
/* substream id */
const
unsigned
i_frame_size
=
bs_read
(
&
s
,
11
);
if
(
i_frame_size
<
2
)
return
VLC_EGENERIC
;
p_header
->
i_size
=
2
*
(
i_frame_size
+
1
);
const
unsigned
i_fscod
=
bs_read
(
&
s
,
2
);
if
(
i_fscod
==
0x03
)
{
const
unsigned
i_fscod2
=
bs_read
(
&
s
,
2
);
if
(
i_fscod2
==
0X03
)
return
VLC_EGENERIC
;
p_header
->
i_rate
=
pi_samplerate
[
i_fscod2
]
/
2
;
i_numblkscod
=
6
;
}
else
{
static
const
int
pi_blocks
[
4
]
=
{
1
,
2
,
3
,
6
};
p_header
->
i_rate
=
pi_samplerate
[
i_fscod
];
i_numblkscod
=
pi_blocks
[
bs_read
(
&
s
,
2
)];
}
const
unsigned
i_acmod
=
bs_read
(
&
s
,
3
);
const
unsigned
i_lfeon
=
bs_read1
(
&
s
);
p_header
->
i_channels
=
p_acmod
[
i_acmod
].
i_count
+
i_lfeon
;
p_header
->
i_channels_conf
=
p_acmod
[
i_acmod
].
i_configuration
|
(
i_lfeon
?
AOUT_CHAN_LFE
:
0
);
p_header
->
i_bitrate
=
8
*
p_header
->
i_size
*
(
p_header
->
i_rate
)
/
(
i_numblkscod
*
256
);
p_header
->
b_eac3
=
true
;
return
VLC_SUCCESS
;
}
/**
* It will parse the header AC3 frame and fill vlc_a52_header_t* if
* it is valid or return VLC_EGENERIC.
*
* XXX It will only recognize big endian bitstream ie starting with 0x0b, 0x77
*/
static
inline
int
vlc_a52_header_Parse
(
vlc_a52_header_t
*
p_header
,
const
uint8_t
*
p_buffer
,
int
i_buffer
)
{
static
const
vlc_a52_acmod_t
p_acmod
[
8
]
=
{
{
2
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_DUALMONO
},
/* Dual-channel 1+1 */
{
1
,
AOUT_CHAN_CENTER
},
/* Mono 1/0 */
{
2
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
},
/* Stereo 2/0 */
{
3
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
},
/* 3F 3/0 */
{
3
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_REARCENTER
},
/* 2F1R 2/1 */
{
4
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARCENTER
},
/* 3F1R 3/1 */
{
5
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
},
/* 2F2R 2/2 */
{
6
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
},
/* 3F2R 3/2 */
};
if
(
i_buffer
<
VLC_A52_HEADER_SIZE
)
return
VLC_EGENERIC
;
/* Check synword */
if
(
p_buffer
[
0
]
!=
0x0b
||
p_buffer
[
1
]
!=
0x77
)
return
VLC_EGENERIC
;
/* Check bsid */
const
int
bsid
=
p_buffer
[
5
]
>>
3
;
if
(
bsid
>
16
)
return
VLC_EGENERIC
;
if
(
bsid
<=
10
)
{
if
(
vlc_a52_header_ParseAc3
(
p_header
,
p_buffer
,
p_acmod
)
)
return
VLC_EGENERIC
;
}
else
{
if
(
vlc_a52_header_ParseEac3
(
p_header
,
p_buffer
,
p_acmod
)
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
#endif
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