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
d98042dd
Commit
d98042dd
authored
Aug 24, 2013
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mp4a packetizer: cosmetics
parent
398d9abf
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
346 additions
and
481 deletions
+346
-481
modules/packetizer/mpeg4audio.c
modules/packetizer/mpeg4audio.c
+346
-481
No files found.
modules/packetizer/mpeg4audio.c
View file @
d98042dd
...
@@ -159,102 +159,92 @@ static const int pi_sample_rates[16] =
...
@@ -159,102 +159,92 @@ static const int pi_sample_rates[16] =
/****************************************************************************
/****************************************************************************
* Local prototypes
* Local prototypes
****************************************************************************/
****************************************************************************/
static
int
OpenPacketizer
(
vlc_object_t
*
);
static
int
OpenPacketizer
(
vlc_object_t
*
);
static
void
ClosePacketizer
(
vlc_object_t
*
);
static
void
ClosePacketizer
(
vlc_object_t
*
);
static
block_t
*
PacketizeRawBlock
(
decoder_t
*
,
block_t
**
);
static
block_t
*
PacketizeRawBlock
(
decoder_t
*
,
block_t
**
);
static
block_t
*
PacketizeStreamBlock
(
decoder_t
*
,
block_t
**
);
static
block_t
*
PacketizeStreamBlock
(
decoder_t
*
,
block_t
**
);
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
*****************************************************************************/
*****************************************************************************/
vlc_module_begin
()
vlc_module_begin
()
set_category
(
CAT_SOUT
)
set_category
(
CAT_SOUT
)
set_subcategory
(
SUBCAT_SOUT_PACKETIZER
)
set_subcategory
(
SUBCAT_SOUT_PACKETIZER
)
set_description
(
N_
(
"MPEG4 audio packetizer"
)
)
set_description
(
N_
(
"MPEG4 audio packetizer"
)
)
set_capability
(
"packetizer"
,
50
)
set_capability
(
"packetizer"
,
50
)
set_callbacks
(
OpenPacketizer
,
ClosePacketizer
)
set_callbacks
(
OpenPacketizer
,
ClosePacketizer
)
vlc_module_end
()
vlc_module_end
()
/*****************************************************************************
/*****************************************************************************
* OpenPacketizer: probe the packetizer and return score
* OpenPacketizer: probe the packetizer and return score
*****************************************************************************/
*****************************************************************************/
static
int
OpenPacketizer
(
vlc_object_t
*
p_this
)
static
int
OpenPacketizer
(
vlc_object_t
*
p_this
)
{
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
;
decoder_sys_t
*
p_sys
;
if
(
p_dec
->
fmt_in
.
i_codec
!=
VLC_CODEC_MP4A
)
if
(
p_dec
->
fmt_in
.
i_codec
!=
VLC_CODEC_MP4A
)
{
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
/* Allocate the memory needed to store the decoder's structure */
/* Allocate the memory needed to store the decoder's structure */
if
(
(
p_dec
->
p_sys
=
p_sys
=
if
((
p_dec
->
p_sys
=
p_sys
=
(
decoder_sys_t
*
)
malloc
(
sizeof
(
decoder_sys_t
)))
==
NULL
)
(
decoder_sys_t
*
)
malloc
(
sizeof
(
decoder_sys_t
))
)
==
NULL
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
/* Misc init */
/* Misc init */
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
date_Set
(
&
p_sys
->
end_date
,
0
);
date_Set
(
&
p_sys
->
end_date
,
0
);
block_BytestreamInit
(
&
p_sys
->
bytestream
);
block_BytestreamInit
(
&
p_sys
->
bytestream
);
p_sys
->
b_latm_cfg
=
false
;
p_sys
->
b_latm_cfg
=
false
;
/* Set output properties */
/* Set output properties */
p_dec
->
fmt_out
.
i_cat
=
AUDIO_ES
;
p_dec
->
fmt_out
.
i_cat
=
AUDIO_ES
;
p_dec
->
fmt_out
.
i_codec
=
VLC_CODEC_MP4A
;
p_dec
->
fmt_out
.
i_codec
=
VLC_CODEC_MP4A
;
msg_Dbg
(
p_dec
,
"running MPEG4 audio packetizer"
);
msg_Dbg
(
p_dec
,
"running MPEG4 audio packetizer"
);
if
(
p_dec
->
fmt_in
.
i_extra
>
0
)
if
(
p_dec
->
fmt_in
.
i_extra
>
0
)
{
{
uint8_t
*
p_config
=
(
uint8_t
*
)
p_dec
->
fmt_in
.
p_extra
;
uint8_t
*
p_config
=
(
uint8_t
*
)
p_dec
->
fmt_in
.
p_extra
;
int
i_index
;
int
i_index
;
i_index
=
(
(
p_config
[
0
]
<<
1
)
|
(
p_config
[
1
]
>>
7
)
)
&
0x0f
;
i_index
=
((
p_config
[
0
]
<<
1
)
|
(
p_config
[
1
]
>>
7
))
&
0x0f
;
if
(
i_index
!=
0x0f
)
if
(
i_index
!=
0x0f
)
{
{
p_dec
->
fmt_out
.
audio
.
i_rate
=
pi_sample_rates
[
i_index
];
p_dec
->
fmt_out
.
audio
.
i_rate
=
pi_sample_rates
[
i_index
];
p_dec
->
fmt_out
.
audio
.
i_frame_length
=
p_dec
->
fmt_out
.
audio
.
i_frame_length
=
((
p_config
[
1
]
>>
2
)
&
0x01
)
?
960
:
1024
;
((
p_config
[
1
]
>>
2
)
&
0x01
)
?
960
:
1024
;
}
}
else
{
else
p_dec
->
fmt_out
.
audio
.
i_rate
=
((
p_config
[
1
]
&
0x7f
)
<<
17
)
|
{
(
p_config
[
2
]
<<
9
)
|
(
p_config
[
3
]
<<
1
)
|
p_dec
->
fmt_out
.
audio
.
i_rate
=
(
(
p_config
[
1
]
&
0x7f
)
<<
17
)
|
(
p_config
[
4
]
>>
7
);
(
p_config
[
2
]
<<
9
)
|
(
p_config
[
3
]
<<
1
)
|
(
p_config
[
4
]
>>
7
);
p_dec
->
fmt_out
.
audio
.
i_frame_length
=
p_dec
->
fmt_out
.
audio
.
i_frame_length
=
((
p_config
[
4
]
>>
2
)
&
0x01
)
?
960
:
1024
;
((
p_config
[
4
]
>>
2
)
&
0x01
)
?
960
:
1024
;
}
}
p_dec
->
fmt_out
.
audio
.
i_channels
=
p_dec
->
fmt_out
.
audio
.
i_channels
=
(
p_config
[
i_index
==
0x0f
?
4
:
1
]
>>
3
)
&
0x0f
;
(
p_config
[
i_index
==
0x0f
?
4
:
1
]
>>
3
)
&
0x0f
;
msg_Dbg
(
p_dec
,
"AAC %dHz %d samples/frame"
,
msg_Dbg
(
p_dec
,
"AAC %dHz %d samples/frame"
,
p_dec
->
fmt_out
.
audio
.
i_rate
,
p_dec
->
fmt_out
.
audio
.
i_rate
,
p_dec
->
fmt_out
.
audio
.
i_frame_length
);
p_dec
->
fmt_out
.
audio
.
i_frame_length
);
date_Init
(
&
p_sys
->
end_date
,
p_dec
->
fmt_out
.
audio
.
i_rate
,
1
);
date_Init
(
&
p_sys
->
end_date
,
p_dec
->
fmt_out
.
audio
.
i_rate
,
1
);
p_dec
->
fmt_out
.
i_extra
=
p_dec
->
fmt_in
.
i_extra
;
p_dec
->
fmt_out
.
i_extra
=
p_dec
->
fmt_in
.
i_extra
;
p_dec
->
fmt_out
.
p_extra
=
malloc
(
p_dec
->
fmt_in
.
i_extra
);
p_dec
->
fmt_out
.
p_extra
=
malloc
(
p_dec
->
fmt_in
.
i_extra
);
if
(
!
p_dec
->
fmt_out
.
p_extra
)
if
(
!
p_dec
->
fmt_out
.
p_extra
)
{
{
p_dec
->
fmt_out
.
i_extra
=
0
;
p_dec
->
fmt_out
.
i_extra
=
0
;
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
}
}
memcpy
(
p_dec
->
fmt_out
.
p_extra
,
p_dec
->
fmt_in
.
p_extra
,
memcpy
(
p_dec
->
fmt_out
.
p_extra
,
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
p_dec
->
fmt_in
.
i_extra
);
/* Set callback */
/* Set callback */
p_dec
->
pf_packetize
=
PacketizeRawBlock
;
p_dec
->
pf_packetize
=
PacketizeRawBlock
;
p_sys
->
i_type
=
TYPE_RAW
;
p_sys
->
i_type
=
TYPE_RAW
;
}
}
else
{
else
msg_Dbg
(
p_dec
,
"no decoder specific info, must be an ADTS or LOAS stream"
);
{
msg_Dbg
(
p_dec
,
"no decoder specific info, must be an ADTS or LOAS stream"
);
date_Init
(
&
p_sys
->
end_date
,
p_dec
->
fmt_in
.
audio
.
i_rate
,
1
);
date_Init
(
&
p_sys
->
end_date
,
p_dec
->
fmt_in
.
audio
.
i_rate
,
1
);
/* We will try to create a AAC Config from adts/loas */
/* We will try to create a AAC Config from adts/loas */
p_dec
->
fmt_out
.
i_extra
=
0
;
p_dec
->
fmt_out
.
i_extra
=
0
;
...
@@ -273,39 +263,36 @@ static int OpenPacketizer( vlc_object_t *p_this )
...
@@ -273,39 +263,36 @@ static int OpenPacketizer( vlc_object_t *p_this )
****************************************************************************
****************************************************************************
* This function must be fed with complete frames.
* This function must be fed with complete frames.
****************************************************************************/
****************************************************************************/
static
block_t
*
PacketizeRawBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
static
block_t
*
PacketizeRawBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_block
;
block_t
*
p_block
;
if
(
!
pp_block
||
!*
pp_block
)
return
NULL
;
if
(
!
pp_block
||
!*
pp_block
)
return
NULL
;
if
(
(
*
pp_block
)
->
i_flags
&
(
BLOCK_FLAG_DISCONTINUITY
|
BLOCK_FLAG_CORRUPTED
)
)
if
((
*
pp_block
)
->
i_flags
&
(
BLOCK_FLAG_DISCONTINUITY
|
BLOCK_FLAG_CORRUPTED
))
{
{
date_Set
(
&
p_sys
->
end_date
,
0
);
date_Set
(
&
p_sys
->
end_date
,
0
);
block_Release
(
*
pp_block
);
block_Release
(
*
pp_block
);
return
NULL
;
return
NULL
;
}
}
p_block
=
*
pp_block
;
p_block
=
*
pp_block
;
*
pp_block
=
NULL
;
/* Don't reuse this block */
*
pp_block
=
NULL
;
/* Don't reuse this block */
if
(
!
date_Get
(
&
p_sys
->
end_date
)
&&
p_block
->
i_pts
<=
VLC_TS_INVALID
)
if
(
!
date_Get
(
&
p_sys
->
end_date
)
&&
p_block
->
i_pts
<=
VLC_TS_INVALID
)
{
{
/* We've just started the stream, wait for the first PTS. */
/* We've just started the stream, wait for the first PTS. */
block_Release
(
p_block
);
block_Release
(
p_block
);
return
NULL
;
return
NULL
;
}
}
else
if
(
p_block
->
i_pts
>
VLC_TS_INVALID
&&
else
if
(
p_block
->
i_pts
>
VLC_TS_INVALID
&&
p_block
->
i_pts
!=
date_Get
(
&
p_sys
->
end_date
))
{
p_block
->
i_pts
!=
date_Get
(
&
p_sys
->
end_date
)
)
date_Set
(
&
p_sys
->
end_date
,
p_block
->
i_pts
);
{
date_Set
(
&
p_sys
->
end_date
,
p_block
->
i_pts
);
}
}
p_block
->
i_pts
=
p_block
->
i_dts
=
date_Get
(
&
p_sys
->
end_date
);
p_block
->
i_pts
=
p_block
->
i_dts
=
date_Get
(
&
p_sys
->
end_date
);
p_block
->
i_length
=
date_Increment
(
&
p_sys
->
end_date
,
p_block
->
i_length
=
date_Increment
(
&
p_sys
->
end_date
,
p_dec
->
fmt_out
.
audio
.
i_frame_length
)
-
p_block
->
i_pts
;
p_dec
->
fmt_out
.
audio
.
i_frame_length
)
-
p_block
->
i_pts
;
return
p_block
;
return
p_block
;
}
}
...
@@ -313,17 +300,17 @@ static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -313,17 +300,17 @@ static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block )
/****************************************************************************
/****************************************************************************
* ADTS helpers
* ADTS helpers
****************************************************************************/
****************************************************************************/
static
int
ADTSSyncInfo
(
decoder_t
*
p_dec
,
const
uint8_t
*
p_buf
,
static
int
ADTSSyncInfo
(
decoder_t
*
p_dec
,
const
uint8_t
*
p_buf
,
unsigned
int
*
pi_channels
,
unsigned
int
*
pi_channels
,
unsigned
int
*
pi_sample_rate
,
unsigned
int
*
pi_sample_rate
,
unsigned
int
*
pi_frame_length
,
unsigned
int
*
pi_frame_length
,
unsigned
int
*
pi_header_size
)
unsigned
int
*
pi_header_size
)
{
{
int
i_profile
,
i_sample_rate_idx
,
i_frame_size
;
int
i_profile
,
i_sample_rate_idx
,
i_frame_size
;
bool
b_crc
;
bool
b_crc
;
/* Fixed header between frames */
/* Fixed header between frames */
//int i_id = (
(p_buf[1] >> 3) & 0x01) ? 2 : 4; /* MPEG-2 or 4 */
//int i_id = ((p_buf[1] >> 3) & 0x01) ? 2 : 4; /* MPEG-2 or 4 */
b_crc
=
!
(
p_buf
[
1
]
&
0x01
);
b_crc
=
!
(
p_buf
[
1
]
&
0x01
);
i_profile
=
p_buf
[
2
]
>>
6
;
i_profile
=
p_buf
[
2
]
>>
6
;
i_sample_rate_idx
=
(
p_buf
[
2
]
>>
2
)
&
0x0f
;
i_sample_rate_idx
=
(
p_buf
[
2
]
>>
2
)
&
0x0f
;
...
@@ -343,47 +330,39 @@ static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
...
@@ -343,47 +330,39 @@ static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
//uint16_t buffer_fullness = ((p_buf[5] & 0x1f) << 6) | (p_buf[6] >> 2);
//uint16_t buffer_fullness = ((p_buf[5] & 0x1f) << 6) | (p_buf[6] >> 2);
unsigned
short
i_raw_blocks_in_frame
=
p_buf
[
6
]
&
0x03
;
unsigned
short
i_raw_blocks_in_frame
=
p_buf
[
6
]
&
0x03
;
if
(
!*
pi_sample_rate
||
!
i_frame_size
)
if
(
!*
pi_sample_rate
||
!
i_frame_size
)
{
{
msg_Warn
(
p_dec
,
"Invalid ADTS header"
);
msg_Warn
(
p_dec
,
"Invalid ADTS header"
);
return
0
;
return
0
;
}
}
*
pi_frame_length
=
1024
;
*
pi_frame_length
=
1024
;
if
(
i_raw_blocks_in_frame
==
0
)
if
(
i_raw_blocks_in_frame
==
0
)
{
{
if
(
b_crc
)
{
if
(
b_crc
)
msg_Warn
(
p_dec
,
"ADTS CRC not supported"
);
{
msg_Warn
(
p_dec
,
"ADTS CRC not supported"
);
//uint16_t crc = (p_buf[7] << 8) | p_buf[8];
//uint16_t crc = (p_buf[7] << 8) | p_buf[8];
}
}
}
}
else
{
else
msg_Err
(
p_dec
,
"Multiple blocks per frame in ADTS not supported"
);
{
msg_Err
(
p_dec
,
"Multiple blocks per frame in ADTS not supported"
);
return
0
;
return
0
;
#if 0
#if 0
int i;
int i;
const uint8_t *p_pos = p_buf + 7;
const uint8_t *p_pos = p_buf + 7;
uint16_t crc_block;
uint16_t crc_block;
uint16_t i_block_pos[3];
uint16_t i_block_pos[3];
if( b_crc )
if (b_crc) {
{
for (i = 0 ; i < i_raw_blocks_in_frame ; i++) {
for( i = 0 ; i < i_raw_blocks_in_frame ; i++ )
/* the 1st block's position is known ... */
{ /* the 1st block's position is known ... */
i_block_pos[i] = (*p_pos << 8) | *(p_pos+1);
i_block_pos[i] = (*p_pos << 8) | *(p_pos+1);
p_pos += 2;
p_pos += 2;
}
}
crc_block = (*p_pos << 8) | *(p_pos+1);
crc_block = (*p_pos << 8) | *(p_pos+1);
p_pos += 2;
p_pos += 2;
}
}
for( i = 0 ; i <= i_raw_blocks_in_frame ; i++ )
for (i = 0 ; i <= i_raw_blocks_in_frame ; i++) {
{
//read 1 block
//read 1 block
if( b_crc )
if (b_crc) {
{
msg_Err(p_dec, "ADTS CRC not supported");
msg_Err( p_dec, "ADTS CRC not supported" );
//uint16_t crc = (*p_pos << 8) | *(p_pos+1);
//uint16_t crc = (*p_pos << 8) | *(p_pos+1);
//p_pos += 2;
//p_pos += 2;
}
}
...
@@ -393,11 +372,9 @@ static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
...
@@ -393,11 +372,9 @@ static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
/* Build the decoder specific info header */
/* Build the decoder specific info header */
if
(
!
p_dec
->
fmt_out
.
i_extra
)
if
(
!
p_dec
->
fmt_out
.
i_extra
)
{
{
p_dec
->
fmt_out
.
p_extra
=
malloc
(
2
);
p_dec
->
fmt_out
.
p_extra
=
malloc
(
2
);
if
(
!
p_dec
->
fmt_out
.
p_extra
)
{
if
(
!
p_dec
->
fmt_out
.
p_extra
)
{
p_dec
->
fmt_out
.
i_extra
=
0
;
p_dec
->
fmt_out
.
i_extra
=
0
;
return
0
;
return
0
;
}
}
...
@@ -417,94 +394,87 @@ static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
...
@@ -417,94 +394,87 @@ static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
/****************************************************************************
/****************************************************************************
* LOAS helpers
* LOAS helpers
****************************************************************************/
****************************************************************************/
static
int
LOASSyncInfo
(
uint8_t
p_header
[
LOAS_HEADER_SIZE
],
unsigned
int
*
pi_header_size
)
static
int
LOASSyncInfo
(
uint8_t
p_header
[
LOAS_HEADER_SIZE
],
unsigned
int
*
pi_header_size
)
{
{
*
pi_header_size
=
3
;
*
pi_header_size
=
3
;
return
(
(
p_header
[
1
]
&
0x1f
)
<<
8
)
+
p_header
[
2
];
return
(
(
p_header
[
1
]
&
0x1f
)
<<
8
)
+
p_header
[
2
];
}
}
static
int
Mpeg4GAProgramConfigElement
(
bs_t
*
s
)
static
int
Mpeg4GAProgramConfigElement
(
bs_t
*
s
)
{
{
/* TODO compute channels count ? */
/* TODO compute channels count ? */
int
i_tag
=
bs_read
(
s
,
4
);
int
i_tag
=
bs_read
(
s
,
4
);
if
(
i_tag
!=
0x05
)
if
(
i_tag
!=
0x05
)
return
-
1
;
return
-
1
;
bs_skip
(
s
,
2
+
4
);
// object type + sampling index
bs_skip
(
s
,
2
+
4
);
// object type + sampling index
int
i_num_front
=
bs_read
(
s
,
4
);
int
i_num_front
=
bs_read
(
s
,
4
);
int
i_num_side
=
bs_read
(
s
,
4
);
int
i_num_side
=
bs_read
(
s
,
4
);
int
i_num_back
=
bs_read
(
s
,
4
);
int
i_num_back
=
bs_read
(
s
,
4
);
int
i_num_lfe
=
bs_read
(
s
,
2
);
int
i_num_lfe
=
bs_read
(
s
,
2
);
int
i_num_assoc_data
=
bs_read
(
s
,
3
);
int
i_num_assoc_data
=
bs_read
(
s
,
3
);
int
i_num_valid_cc
=
bs_read
(
s
,
4
);
int
i_num_valid_cc
=
bs_read
(
s
,
4
);
if
(
bs_read1
(
s
)
)
if
(
bs_read1
(
s
)
)
bs_skip
(
s
,
4
);
// mono downmix
bs_skip
(
s
,
4
);
// mono downmix
if
(
bs_read1
(
s
)
)
if
(
bs_read1
(
s
)
)
bs_skip
(
s
,
4
);
// stereo downmix
bs_skip
(
s
,
4
);
// stereo downmix
if
(
bs_read1
(
s
)
)
if
(
bs_read1
(
s
)
)
bs_skip
(
s
,
2
+
1
);
// matrix downmix + pseudo_surround
bs_skip
(
s
,
2
+
1
);
// matrix downmix + pseudo_surround
bs_skip
(
s
,
i_num_front
*
(
1
+
4
)
);
bs_skip
(
s
,
i_num_front
*
(
1
+
4
)
);
bs_skip
(
s
,
i_num_side
*
(
1
+
4
)
);
bs_skip
(
s
,
i_num_side
*
(
1
+
4
)
);
bs_skip
(
s
,
i_num_back
*
(
1
+
4
)
);
bs_skip
(
s
,
i_num_back
*
(
1
+
4
)
);
bs_skip
(
s
,
i_num_lfe
*
(
4
)
);
bs_skip
(
s
,
i_num_lfe
*
(
4
)
);
bs_skip
(
s
,
i_num_assoc_data
*
(
4
)
);
bs_skip
(
s
,
i_num_assoc_data
*
(
4
)
);
bs_skip
(
s
,
i_num_valid_cc
*
(
5
)
);
bs_skip
(
s
,
i_num_valid_cc
*
(
5
)
);
bs_align
(
s
);
bs_align
(
s
);
int
i_comment
=
bs_read
(
s
,
8
);
int
i_comment
=
bs_read
(
s
,
8
);
bs_skip
(
s
,
i_comment
*
8
);
bs_skip
(
s
,
i_comment
*
8
);
return
0
;
return
0
;
}
}
static
int
Mpeg4GASpecificConfig
(
mpeg4_cfg_t
*
p_cfg
,
bs_t
*
s
)
static
int
Mpeg4GASpecificConfig
(
mpeg4_cfg_t
*
p_cfg
,
bs_t
*
s
)
{
{
p_cfg
->
i_frame_length
=
bs_read1
(
s
)
?
960
:
1024
;
p_cfg
->
i_frame_length
=
bs_read1
(
s
)
?
960
:
1024
;
if
(
bs_read1
(
s
)
)
// depend on core coder
if
(
bs_read1
(
s
))
// depend on core coder
bs_skip
(
s
,
14
);
// core coder delay
bs_skip
(
s
,
14
);
// core coder delay
int
i_extension_flag
=
bs_read1
(
s
);
int
i_extension_flag
=
bs_read1
(
s
);
if
(
p_cfg
->
i_channel
==
0
)
if
(
p_cfg
->
i_channel
==
0
)
{
Mpeg4GAProgramConfigElement
(
s
);
Mpeg4GAProgramConfigElement
(
s
);
if
(
p_cfg
->
i_object_type
==
6
||
p_cfg
->
i_object_type
==
20
)
}
bs_skip
(
s
,
3
);
// layer
if
(
p_cfg
->
i_object_type
==
6
||
p_cfg
->
i_object_type
==
20
)
bs_skip
(
s
,
3
);
// layer
if
(
i_extension_flag
)
{
if
(
p_cfg
->
i_object_type
==
22
)
if
(
i_extension_flag
)
bs_skip
(
s
,
5
+
11
);
// numOfSubFrame + layer length
{
if
(
p_cfg
->
i_object_type
==
17
||
p_cfg
->
i_object_type
==
19
||
if
(
p_cfg
->
i_object_type
==
22
)
p_cfg
->
i_object_type
==
20
||
p_cfg
->
i_object_type
==
23
)
{
bs_skip
(
s
,
1
+
1
+
1
);
// ER data : section scale spectral */
bs_skip
(
s
,
5
+
11
);
// numOfSubFrame + layer length
if
(
bs_read1
(
s
))
// extension 3
}
fprintf
(
stderr
,
"Mpeg4GASpecificConfig: error 1
\n
"
);
if
(
p_cfg
->
i_object_type
==
17
||
p_cfg
->
i_object_type
==
19
||
p_cfg
->
i_object_type
==
20
||
p_cfg
->
i_object_type
==
23
)
{
bs_skip
(
s
,
1
+
1
+
1
);
// ER data : section scale spectral */
}
if
(
bs_read1
(
s
)
)
// extension 3
fprintf
(
stderr
,
"Mpeg4GASpecificConfig: error 1
\n
"
);
}
}
return
0
;
return
0
;
}
}
static
int
Mpeg4ReadAudioObjectType
(
bs_t
*
s
)
static
int
Mpeg4ReadAudioObjectType
(
bs_t
*
s
)
{
{
int
i_type
=
bs_read
(
s
,
5
);
int
i_type
=
bs_read
(
s
,
5
);
if
(
i_type
==
31
)
if
(
i_type
==
31
)
i_type
=
32
+
bs_read
(
s
,
6
);
i_type
=
32
+
bs_read
(
s
,
6
);
return
i_type
;
return
i_type
;
}
}
static
int
Mpeg4ReadAudioSamplerate
(
bs_t
*
s
)
static
int
Mpeg4ReadAudioSamplerate
(
bs_t
*
s
)
{
{
int
i_index
=
bs_read
(
s
,
4
);
int
i_index
=
bs_read
(
s
,
4
);
if
(
i_index
!=
0x0f
)
if
(
i_index
!=
0x0f
)
return
pi_sample_rates
[
i_index
];
return
pi_sample_rates
[
i_index
];
return
bs_read
(
s
,
24
);
return
bs_read
(
s
,
24
);
}
}
static
int
Mpeg4ReadAudioSpecificInfo
(
mpeg4_cfg_t
*
p_cfg
,
int
*
pi_extra
,
uint8_t
*
p_extra
,
bs_t
*
s
,
int
i_max_size
)
static
int
Mpeg4ReadAudioSpecificInfo
(
mpeg4_cfg_t
*
p_cfg
,
int
*
pi_extra
,
uint8_t
*
p_extra
,
bs_t
*
s
,
int
i_max_size
)
{
{
#if 0
#if 0
static const char *ppsz_otype[] = {
static const char *ppsz_otype[] = {
...
@@ -526,44 +496,43 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
...
@@ -526,44 +496,43 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
"DST",
"DST",
};
};
#endif
#endif
const
int
i_pos_start
=
bs_pos
(
s
);
const
int
i_pos_start
=
bs_pos
(
s
);
bs_t
s_sav
=
*
s
;
bs_t
s_sav
=
*
s
;
int
i_bits
;
int
i_bits
;
int
i
;
int
i
;
memset
(
p_cfg
,
0
,
sizeof
(
*
p_cfg
)
);
memset
(
p_cfg
,
0
,
sizeof
(
*
p_cfg
)
);
*
pi_extra
=
0
;
*
pi_extra
=
0
;
p_cfg
->
i_object_type
=
Mpeg4ReadAudioObjectType
(
s
);
p_cfg
->
i_object_type
=
Mpeg4ReadAudioObjectType
(
s
);
p_cfg
->
i_samplerate
=
Mpeg4ReadAudioSamplerate
(
s
);
p_cfg
->
i_samplerate
=
Mpeg4ReadAudioSamplerate
(
s
);
p_cfg
->
i_channel
=
bs_read
(
s
,
4
);
p_cfg
->
i_channel
=
bs_read
(
s
,
4
);
if
(
p_cfg
->
i_channel
==
7
)
if
(
p_cfg
->
i_channel
==
7
)
p_cfg
->
i_channel
=
8
;
// 7.1
p_cfg
->
i_channel
=
8
;
// 7.1
else
if
(
p_cfg
->
i_channel
>=
8
)
else
if
(
p_cfg
->
i_channel
>=
8
)
p_cfg
->
i_channel
=
-
1
;
p_cfg
->
i_channel
=
-
1
;
p_cfg
->
i_sbr
=
-
1
;
p_cfg
->
i_sbr
=
-
1
;
p_cfg
->
i_ps
=
-
1
;
p_cfg
->
i_ps
=
-
1
;
p_cfg
->
extension
.
i_object_type
=
0
;
p_cfg
->
extension
.
i_object_type
=
0
;
p_cfg
->
extension
.
i_samplerate
=
0
;
p_cfg
->
extension
.
i_samplerate
=
0
;
if
(
p_cfg
->
i_object_type
==
5
||
p_cfg
->
i_object_type
==
29
)
if
(
p_cfg
->
i_object_type
==
5
||
p_cfg
->
i_object_type
==
29
)
{
{
p_cfg
->
i_sbr
=
1
;
p_cfg
->
i_sbr
=
1
;
if
(
p_cfg
->
i_object_type
==
29
)
if
(
p_cfg
->
i_object_type
==
29
)
p_cfg
->
i_ps
=
1
;
p_cfg
->
i_ps
=
1
;
p_cfg
->
extension
.
i_object_type
=
5
;
p_cfg
->
extension
.
i_object_type
=
5
;
p_cfg
->
extension
.
i_samplerate
=
Mpeg4ReadAudioSamplerate
(
s
);
p_cfg
->
extension
.
i_samplerate
=
Mpeg4ReadAudioSamplerate
(
s
);
p_cfg
->
i_object_type
=
Mpeg4ReadAudioObjectType
(
s
);
p_cfg
->
i_object_type
=
Mpeg4ReadAudioObjectType
(
s
);
}
}
switch
(
p_cfg
->
i_object_type
)
switch
(
p_cfg
->
i_object_type
)
{
{
case
1
:
case
2
:
case
3
:
case
4
:
case
1
:
case
2
:
case
3
:
case
4
:
case
6
:
case
7
:
case
6
:
case
7
:
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
Mpeg4GASpecificConfig
(
p_cfg
,
s
);
Mpeg4GASpecificConfig
(
p_cfg
,
s
);
break
;
break
;
case
8
:
case
8
:
// CelpSpecificConfig();
// CelpSpecificConfig();
...
@@ -602,109 +571,87 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
...
@@ -602,109 +571,87 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
// error
// error
break
;
break
;
}
}
switch
(
p_cfg
->
i_object_type
)
switch
(
p_cfg
->
i_object_type
)
{
{
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
case
24
:
case
25
:
case
26
:
case
27
:
case
24
:
case
25
:
case
26
:
case
27
:
{
{
int
epConfig
=
bs_read
(
s
,
2
);
int
epConfig
=
bs_read
(
s
,
2
);
if
(
epConfig
==
2
||
epConfig
==
3
)
if
(
epConfig
==
2
||
epConfig
==
3
)
{
//ErrorProtectionSpecificConfig();
//ErrorProtectionSpecificConfig();
}
if
(
epConfig
==
3
)
if
(
epConfig
==
3
)
if
(
bs_read1
(
s
))
{
{
// TODO : directMapping
int
directMapping
=
bs_read1
(
s
);
if
(
directMapping
)
{
// tbd ...
}
}
}
break
;
break
;
}
}
default:
default:
break
;
break
;
}
}
if
(
p_cfg
->
extension
.
i_object_type
!=
5
&&
i_max_size
>
0
&&
i_max_size
-
(
bs_pos
(
s
)
-
i_pos_start
)
>=
16
&&
if
(
p_cfg
->
extension
.
i_object_type
!=
5
&&
i_max_size
>
0
&&
i_max_size
-
(
bs_pos
(
s
)
-
i_pos_start
)
>=
16
&&
bs_read
(
s
,
11
)
==
0x2b7
)
bs_read
(
s
,
11
)
==
0x2b7
)
{
{
p_cfg
->
extension
.
i_object_type
=
Mpeg4ReadAudioObjectType
(
s
);
p_cfg
->
extension
.
i_object_type
=
Mpeg4ReadAudioObjectType
(
s
);
if
(
p_cfg
->
extension
.
i_object_type
==
5
)
{
if
(
p_cfg
->
extension
.
i_object_type
==
5
)
p_cfg
->
i_sbr
=
bs_read1
(
s
);
{
if
(
p_cfg
->
i_sbr
==
1
)
{
p_cfg
->
i_sbr
=
bs_read1
(
s
);
p_cfg
->
extension
.
i_samplerate
=
Mpeg4ReadAudioSamplerate
(
s
);
if
(
p_cfg
->
i_sbr
==
1
)
if
(
i_max_size
>
0
&&
i_max_size
-
(
bs_pos
(
s
)
-
i_pos_start
)
>=
12
&&
bs_read
(
s
,
11
)
==
0x548
)
{
p_cfg
->
i_ps
=
bs_read1
(
s
);
p_cfg
->
extension
.
i_samplerate
=
Mpeg4ReadAudioSamplerate
(
s
);
if
(
i_max_size
>
0
&&
i_max_size
-
(
bs_pos
(
s
)
-
i_pos_start
)
>=
12
&&
bs_read
(
s
,
11
)
==
0x548
)
{
p_cfg
->
i_ps
=
bs_read1
(
s
);
}
}
}
}
}
}
}
//fprintf(
stderr, "Mpeg4ReadAudioSpecificInfo: t=%s(%d)f=%d c=%d sbr=%d\n",
//fprintf(stderr, "Mpeg4ReadAudioSpecificInfo: t=%s(%d)f=%d c=%d sbr=%d\n",
// ppsz_otype[p_cfg->i_object_type], p_cfg->i_object_type, p_cfg->i_samplerate, p_cfg->i_channel, p_cfg->i_sbr
);
// ppsz_otype[p_cfg->i_object_type], p_cfg->i_object_type, p_cfg->i_samplerate, p_cfg->i_channel, p_cfg->i_sbr);
i_bits
=
bs_pos
(
s
)
-
i_pos_start
;
i_bits
=
bs_pos
(
s
)
-
i_pos_start
;
*
pi_extra
=
__MIN
(
(
i_bits
+
7
)
/
8
,
LATM_MAX_EXTRA_SIZE
);
*
pi_extra
=
__MIN
((
i_bits
+
7
)
/
8
,
LATM_MAX_EXTRA_SIZE
);
for
(
i
=
0
;
i
<
*
pi_extra
;
i
++
)
for
(
i
=
0
;
i
<
*
pi_extra
;
i
++
)
{
{
const
int
i_read
=
__MIN
(
8
,
i_bits
-
8
*
i
);
const
int
i_read
=
__MIN
(
8
,
i_bits
-
8
*
i
);
p_extra
[
i
]
=
bs_read
(
&
s_sav
,
i_read
)
<<
(
8
-
i_read
);
p_extra
[
i
]
=
bs_read
(
&
s_sav
,
i_read
)
<<
(
8
-
i_read
);
}
}
return
i_bits
;
return
i_bits
;
}
}
static
int
LatmGetValue
(
bs_t
*
s
)
static
int
LatmGetValue
(
bs_t
*
s
)
{
{
int
i_bytes
=
bs_read
(
s
,
2
);
int
i_bytes
=
bs_read
(
s
,
2
);
int
v
=
0
;
int
v
=
0
;
int
i
;
for
(
int
i
=
0
;
i
<
i_bytes
;
i
++
)
for
(
i
=
0
;
i
<
i_bytes
;
i
++
)
v
=
(
v
<<
8
)
+
bs_read
(
s
,
8
);
v
=
(
v
<<
8
)
+
bs_read
(
s
,
8
);
return
v
;
return
v
;
}
}
static
int
LatmReadStreamMuxConfiguration
(
latm_mux_t
*
m
,
bs_t
*
s
)
static
int
LatmReadStreamMuxConfiguration
(
latm_mux_t
*
m
,
bs_t
*
s
)
{
{
int
i_mux_version
;
int
i_mux_version
;
int
i_mux_versionA
;
int
i_mux_versionA
;
int
i_program
;
i_mux_version
=
bs_read
(
s
,
1
);
i_mux_version
=
bs_read
(
s
,
1
);
i_mux_versionA
=
0
;
i_mux_versionA
=
0
;
if
(
i_mux_version
)
if
(
i_mux_version
)
i_mux_versionA
=
bs_read
(
s
,
1
);
i_mux_versionA
=
bs_read
(
s
,
1
);
if
(
i_mux_versionA
!=
0
)
/* support only A=0 */
if
(
i_mux_versionA
!=
0
)
/* support only A=0 */
return
-
1
;
return
-
1
;
memset
(
m
,
0
,
sizeof
(
*
m
)
);
memset
(
m
,
0
,
sizeof
(
*
m
)
);
if
(
i_mux_versionA
==
0
)
if
(
i_mux_versionA
==
0
)
{
if
(
i_mux_version
==
1
)
if
(
i_mux_version
==
1
)
{
LatmGetValue
(
s
);
/* taraBufferFullness */
LatmGetValue
(
s
);
/* taraBufferFullness */
}
}
m
->
b_same_time_framing
=
bs_read1
(
s
);
m
->
b_same_time_framing
=
bs_read1
(
s
);
m
->
i_sub_frames
=
1
+
bs_read
(
s
,
6
);
m
->
i_sub_frames
=
1
+
bs_read
(
s
,
6
);
m
->
i_programs
=
1
+
bs_read
(
s
,
4
);
m
->
i_programs
=
1
+
bs_read
(
s
,
4
);
for
(
i_program
=
0
;
i_program
<
m
->
i_programs
;
i_program
++
)
for
(
int
i_program
=
0
;
i_program
<
m
->
i_programs
;
i_program
++
)
{
{
m
->
pi_layers
[
i_program
]
=
1
+
bs_read
(
s
,
3
);
int
i_layer
;
m
->
pi_layers
[
i_program
]
=
1
+
bs_read
(
s
,
3
);
for
(
i_layer
=
0
;
i_layer
<
m
->
pi_layers
[
i_program
];
i_layer
++
)
for
(
int
i_layer
=
0
;
i_layer
<
m
->
pi_layers
[
i_program
];
i_layer
++
)
{
{
latm_stream_t
*
st
=
&
m
->
stream
[
m
->
i_streams
];
latm_stream_t
*
st
=
&
m
->
stream
[
m
->
i_streams
];
bool
b_previous_cfg
;
bool
b_previous_cfg
;
...
@@ -713,48 +660,41 @@ static int LatmReadStreamMuxConfiguration( latm_mux_t *m, bs_t *s )
...
@@ -713,48 +660,41 @@ static int LatmReadStreamMuxConfiguration( latm_mux_t *m, bs_t *s )
st
->
i_layer
=
i_layer
;
st
->
i_layer
=
i_layer
;
b_previous_cfg
=
false
;
b_previous_cfg
=
false
;
if
(
i_program
!=
0
||
i_layer
!=
0
)
if
(
i_program
!=
0
||
i_layer
!=
0
)
b_previous_cfg
=
bs_read1
(
s
);
b_previous_cfg
=
bs_read1
(
s
);
if
(
b_previous_cfg
)
if
(
b_previous_cfg
)
{
{
assert
(
m
->
i_streams
>
0
);
assert
(
m
->
i_streams
>
0
);
st
->
cfg
=
m
->
stream
[
m
->
i_streams
-
1
].
cfg
;
st
->
cfg
=
m
->
stream
[
m
->
i_streams
-
1
].
cfg
;
}
}
else
{
else
{
int
i_cfg_size
=
0
;
int
i_cfg_size
=
0
;
if
(
i_mux_version
==
1
)
if
(
i_mux_version
==
1
)
i_cfg_size
=
LatmGetValue
(
s
);
i_cfg_size
=
LatmGetValue
(
s
);
i_cfg_size
-=
Mpeg4ReadAudioSpecificInfo
(
&
st
->
cfg
,
&
st
->
i_extra
,
st
->
extra
,
s
,
i_cfg_size
);
i_cfg_size
-=
Mpeg4ReadAudioSpecificInfo
(
&
st
->
cfg
,
&
st
->
i_extra
,
st
->
extra
,
s
,
i_cfg_size
);
if
(
i_cfg_size
>
0
)
if
(
i_cfg_size
>
0
)
bs_skip
(
s
,
i_cfg_size
);
bs_skip
(
s
,
i_cfg_size
);
}
}
st
->
i_frame_length_type
=
bs_read
(
s
,
3
);
st
->
i_frame_length_type
=
bs_read
(
s
,
3
);
switch
(
st
->
i_frame_length_type
)
switch
(
st
->
i_frame_length_type
)
{
{
case
0
:
case
0
:
{
{
bs_skip
(
s
,
8
);
/* latmBufferFullnes */
bs_skip
(
s
,
8
);
/* latmBufferFullnes */
if
(
!
m
->
b_same_time_framing
)
if
(
!
m
->
b_same_time_framing
)
{
if
(
st
->
cfg
.
i_object_type
==
6
||
st
->
cfg
.
i_object_type
==
20
||
if
(
st
->
cfg
.
i_object_type
==
6
||
st
->
cfg
.
i_object_type
==
20
||
st
->
cfg
.
i_object_type
==
8
||
st
->
cfg
.
i_object_type
==
24
)
st
->
cfg
.
i_object_type
==
8
||
st
->
cfg
.
i_object_type
==
24
)
bs_skip
(
s
,
6
);
/* eFrameOffset */
{
bs_skip
(
s
,
6
);
/* eFrameOffset */
}
}
break
;
break
;
}
}
case
1
:
case
1
:
st
->
i_frame_length
=
bs_read
(
s
,
9
);
st
->
i_frame_length
=
bs_read
(
s
,
9
);
break
;
break
;
case
3
:
case
4
:
case
5
:
case
3
:
case
4
:
case
5
:
st
->
i_frame_length_index
=
bs_read
(
s
,
6
);
// celp
st
->
i_frame_length_index
=
bs_read
(
s
,
6
);
// celp
break
;
break
;
case
6
:
case
7
:
case
6
:
case
7
:
st
->
i_frame_length_index
=
bs_read
(
s
,
1
);
// hvxc
st
->
i_frame_length_index
=
bs_read
(
s
,
1
);
// hvxc
default:
default:
break
;
break
;
}
}
...
@@ -764,152 +704,120 @@ static int LatmReadStreamMuxConfiguration( latm_mux_t *m, bs_t *s )
...
@@ -764,152 +704,120 @@ static int LatmReadStreamMuxConfiguration( latm_mux_t *m, bs_t *s )
}
}
/* other data */
/* other data */
if
(
bs_read1
(
s
)
)
if
(
bs_read1
(
s
))
{
{
if
(
i_mux_version
==
1
)
if
(
i_mux_version
==
1
)
m
->
i_other_data
=
LatmGetValue
(
s
);
{
else
{
m
->
i_other_data
=
LatmGetValue
(
s
);
}
else
{
int
b_continue
;
int
b_continue
;
do
{
do
{
b_continue
=
bs_read1
(
s
);
b_continue
=
bs_read1
(
s
);
m
->
i_other_data
=
(
m
->
i_other_data
<<
8
)
+
bs_read
(
s
,
8
);
m
->
i_other_data
=
(
m
->
i_other_data
<<
8
)
+
bs_read
(
s
,
8
);
}
while
(
b_continue
);
}
while
(
b_continue
);
}
}
}
}
/* crc */
/* crc */
m
->
i_crc
=
-
1
;
m
->
i_crc
=
-
1
;
if
(
bs_read1
(
s
)
)
if
(
bs_read1
(
s
)
)
m
->
i_crc
=
bs_read
(
s
,
8
);
m
->
i_crc
=
bs_read
(
s
,
8
);
return
0
;
return
0
;
}
}
static
int
LOASParse
(
decoder_t
*
p_dec
,
uint8_t
*
p_buffer
,
int
i_buffer
)
static
int
LOASParse
(
decoder_t
*
p_dec
,
uint8_t
*
p_buffer
,
int
i_buffer
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
bs_t
s
;
bs_t
s
;
int
i_sub
;
int
i_accumulated
=
0
;
int
i_accumulated
=
0
;
bs_init
(
&
s
,
p_buffer
,
i_buffer
);
bs_init
(
&
s
,
p_buffer
,
i_buffer
);
/* Read the stream mux configuration if present */
/* Read the stream mux configuration if present */
if
(
!
bs_read1
(
&
s
)
)
if
(
!
bs_read1
(
&
s
))
{
{
if
(
!
LatmReadStreamMuxConfiguration
(
&
p_sys
->
latm
,
&
s
)
&&
if
(
!
LatmReadStreamMuxConfiguration
(
&
p_sys
->
latm
,
&
s
)
&&
p_sys
->
latm
.
i_streams
>
0
)
{
p_sys
->
latm
.
i_streams
>
0
)
{
const
latm_stream_t
*
st
=
&
p_sys
->
latm
.
stream
[
0
];
const
latm_stream_t
*
st
=
&
p_sys
->
latm
.
stream
[
0
];
p_sys
->
i_channels
=
st
->
cfg
.
i_channel
;
p_sys
->
i_channels
=
st
->
cfg
.
i_channel
;
p_sys
->
i_rate
=
st
->
cfg
.
i_samplerate
;
p_sys
->
i_rate
=
st
->
cfg
.
i_samplerate
;
p_sys
->
i_frame_length
=
st
->
cfg
.
i_frame_length
;
p_sys
->
i_frame_length
=
st
->
cfg
.
i_frame_length
;
if
(
p_sys
->
i_channels
>
0
&&
p_sys
->
i_rate
>
0
&&
if
(
p_sys
->
i_channels
>
0
&&
p_sys
->
i_rate
>
0
&&
p_sys
->
i_frame_length
>
0
)
p_sys
->
i_frame_length
>
0
)
{
{
/* FIXME And if it changes ? */
/* FIXME And if it changes ? */
if
(
!
p_dec
->
fmt_out
.
i_extra
&&
st
->
i_extra
>
0
)
if
(
!
p_dec
->
fmt_out
.
i_extra
&&
st
->
i_extra
>
0
)
{
{
p_dec
->
fmt_out
.
i_extra
=
st
->
i_extra
;
p_dec
->
fmt_out
.
i_extra
=
st
->
i_extra
;
p_dec
->
fmt_out
.
p_extra
=
malloc
(
st
->
i_extra
);
p_dec
->
fmt_out
.
p_extra
=
malloc
(
st
->
i_extra
);
if
(
!
p_dec
->
fmt_out
.
p_extra
)
if
(
!
p_dec
->
fmt_out
.
p_extra
)
{
{
p_dec
->
fmt_out
.
i_extra
=
0
;
p_dec
->
fmt_out
.
i_extra
=
0
;
return
0
;
return
0
;
}
}
memcpy
(
p_dec
->
fmt_out
.
p_extra
,
st
->
extra
,
st
->
i_extra
);
memcpy
(
p_dec
->
fmt_out
.
p_extra
,
st
->
extra
,
st
->
i_extra
);
}
}
p_sys
->
b_latm_cfg
=
true
;
p_sys
->
b_latm_cfg
=
true
;
}
}
}
}
}
}
/* Wait for the configuration */
/* Wait for the configuration */
if
(
!
p_sys
->
b_latm_cfg
)
if
(
!
p_sys
->
b_latm_cfg
)
return
0
;
return
0
;
/* FIXME do we need to split the subframe into independent packet ? */
/* FIXME do we need to split the subframe into independent packet ? */
if
(
p_sys
->
latm
.
i_sub_frames
>
1
)
if
(
p_sys
->
latm
.
i_sub_frames
>
1
)
msg_Err
(
p_dec
,
"latm sub frames not yet supported, please send a sample"
);
msg_Err
(
p_dec
,
"latm sub frames not yet supported, please send a sample"
);
for
(
i_sub
=
0
;
i_sub
<
p_sys
->
latm
.
i_sub_frames
;
i_sub
++
)
for
(
int
i_sub
=
0
;
i_sub
<
p_sys
->
latm
.
i_sub_frames
;
i_sub
++
)
{
{
int
pi_payload
[
LATM_MAX_PROGRAM
][
LATM_MAX_LAYER
];
int
pi_payload
[
LATM_MAX_PROGRAM
][
LATM_MAX_LAYER
];
if
(
p_sys
->
latm
.
b_same_time_framing
)
if
(
p_sys
->
latm
.
b_same_time_framing
)
{
{
int
i_program
;
/* Payload length */
/* Payload length */
for
(
i_program
=
0
;
i_program
<
p_sys
->
latm
.
i_programs
;
i_program
++
)
for
(
int
i_program
=
0
;
i_program
<
p_sys
->
latm
.
i_programs
;
i_program
++
)
{
{
for
(
int
i_layer
=
0
;
i_layer
<
p_sys
->
latm
.
pi_layers
[
i_program
];
i_layer
++
)
{
int
i_layer
;
for
(
i_layer
=
0
;
i_layer
<
p_sys
->
latm
.
pi_layers
[
i_program
];
i_layer
++
)
{
latm_stream_t
*
st
=
&
p_sys
->
latm
.
stream
[
p_sys
->
latm
.
pi_stream
[
i_program
][
i_layer
]];
latm_stream_t
*
st
=
&
p_sys
->
latm
.
stream
[
p_sys
->
latm
.
pi_stream
[
i_program
][
i_layer
]];
if
(
st
->
i_frame_length_type
==
0
)
if
(
st
->
i_frame_length_type
==
0
)
{
{
int
i_payload
=
0
;
int
i_payload
=
0
;
for
(
;;
)
for
(;;)
{
{
int
i_tmp
=
bs_read
(
&
s
,
8
);
int
i_tmp
=
bs_read
(
&
s
,
8
);
i_payload
+=
i_tmp
;
i_payload
+=
i_tmp
;
if
(
i_tmp
!=
255
)
if
(
i_tmp
!=
255
)
break
;
break
;
}
}
pi_payload
[
i_program
][
i_layer
]
=
i_payload
;
pi_payload
[
i_program
][
i_layer
]
=
i_payload
;
}
}
else
if
(
st
->
i_frame_length_type
==
1
)
{
else
if
(
st
->
i_frame_length_type
==
1
)
{
pi_payload
[
i_program
][
i_layer
]
=
st
->
i_frame_length
/
8
;
/* XXX not correct */
pi_payload
[
i_program
][
i_layer
]
=
st
->
i_frame_length
/
8
;
/* XXX not correct */
}
}
else
if
((
st
->
i_frame_length_type
==
3
)
||
else
if
(
(
st
->
i_frame_length_type
==
3
)
||
(
st
->
i_frame_length_type
==
5
)
||
(
st
->
i_frame_length_type
==
5
)
||
(
st
->
i_frame_length_type
==
7
))
{
(
st
->
i_frame_length_type
==
7
)
)
bs_skip
(
&
s
,
2
);
// muxSlotLengthCoded
{
bs_skip
(
&
s
,
2
);
// muxSlotLengthCoded
pi_payload
[
i_program
][
i_layer
]
=
0
;
/* TODO */
pi_payload
[
i_program
][
i_layer
]
=
0
;
/* TODO */
}
}
else
{
else
{
pi_payload
[
i_program
][
i_layer
]
=
0
;
/* TODO */
pi_payload
[
i_program
][
i_layer
]
=
0
;
/* TODO */
}
}
}
}
}
}
/* Payload Data */
/* Payload Data */
for
(
i_program
=
0
;
i_program
<
p_sys
->
latm
.
i_programs
;
i_program
++
)
for
(
int
i_program
=
0
;
i_program
<
p_sys
->
latm
.
i_programs
;
i_program
++
)
{
{
for
(
int
i_layer
=
0
;
i_layer
<
p_sys
->
latm
.
pi_layers
[
i_program
];
i_layer
++
)
{
int
i_layer
;
int
i
;
for
(
i_layer
=
0
;
i_layer
<
p_sys
->
latm
.
pi_layers
[
i_program
];
i_layer
++
)
{
/* XXX we only extract 1 stream */
/* XXX we only extract 1 stream */
if
(
i_program
!=
0
||
i_layer
!=
0
)
if
(
i_program
!=
0
||
i_layer
!=
0
)
break
;
break
;
if
(
pi_payload
[
i_program
][
i_layer
]
<=
0
)
if
(
pi_payload
[
i_program
][
i_layer
]
<=
0
)
continue
;
continue
;
/* FIXME that's slow (and a bit ugly to write in place) */
/* FIXME that's slow (and a bit ugly to write in place) */
for
(
i
=
0
;
i
<
pi_payload
[
i_program
][
i_layer
];
i
++
)
for
(
int
i
=
0
;
i
<
pi_payload
[
i_program
][
i_layer
];
i
++
)
p_buffer
[
i_accumulated
++
]
=
bs_read
(
&
s
,
8
);
p_buffer
[
i_accumulated
++
]
=
bs_read
(
&
s
,
8
);
}
}
}
}
}
}
else
{
else
const
int
i_chunks
=
bs_read
(
&
s
,
4
);
{
const
int
i_chunks
=
bs_read
(
&
s
,
4
);
int
pi_program
[
16
];
int
pi_program
[
16
];
int
pi_layer
[
16
];
int
pi_layer
[
16
];
int
i_chunk
;
msg_Err
(
p_dec
,
"latm without same time frameing not yet supported, please send a sample"
);
msg_Err
(
p_dec
,
"latm without same time frameing not yet supported, please send a sample"
);
for
(
i_chunk
=
0
;
i_chunk
<
i_chunks
;
i_chunk
++
)
for
(
int
i_chunk
=
0
;
i_chunk
<
i_chunks
;
i_chunk
++
)
{
{
const
int
streamIndex
=
bs_read
(
&
s
,
4
);
const
int
streamIndex
=
bs_read
(
&
s
,
4
);
latm_stream_t
*
st
=
&
p_sys
->
latm
.
stream
[
streamIndex
];
latm_stream_t
*
st
=
&
p_sys
->
latm
.
stream
[
streamIndex
];
const
int
i_program
=
st
->
i_program
;
const
int
i_program
=
st
->
i_program
;
const
int
i_layer
=
st
->
i_layer
;
const
int
i_layer
=
st
->
i_layer
;
...
@@ -917,35 +825,25 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
...
@@ -917,35 +825,25 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
pi_program
[
i_chunk
]
=
i_program
;
pi_program
[
i_chunk
]
=
i_program
;
pi_layer
[
i_chunk
]
=
i_layer
;
pi_layer
[
i_chunk
]
=
i_layer
;
if
(
st
->
i_frame_length_type
==
0
)
if
(
st
->
i_frame_length_type
==
0
)
{
{
int
i_payload
=
0
;
int
i_payload
=
0
;
for
(
;;
)
for
(;;)
{
{
int
i_tmp
=
bs_read
(
&
s
,
8
);
int
i_tmp
=
bs_read
(
&
s
,
8
);
i_payload
+=
i_tmp
;
i_payload
+=
i_tmp
;
if
(
i_tmp
!=
255
)
if
(
i_tmp
!=
255
)
break
;
break
;
}
}
pi_payload
[
i_program
][
i_layer
]
=
i_payload
;
pi_payload
[
i_program
][
i_layer
]
=
i_payload
;
bs_skip
(
&
s
,
1
);
// auEndFlag
bs_skip
(
&
s
,
1
);
// auEndFlag
}
}
else
if
(
st
->
i_frame_length_type
==
1
)
{
else
if
(
st
->
i_frame_length_type
==
1
)
{
pi_payload
[
i_program
][
i_layer
]
=
st
->
i_frame_length
/
8
;
/* XXX not correct */
pi_payload
[
i_program
][
i_layer
]
=
st
->
i_frame_length
/
8
;
/* XXX not correct */
}
}
else
if
((
st
->
i_frame_length_type
==
3
)
||
else
if
(
(
st
->
i_frame_length_type
==
3
)
||
(
st
->
i_frame_length_type
==
5
)
||
(
st
->
i_frame_length_type
==
5
)
||
(
st
->
i_frame_length_type
==
7
))
{
(
st
->
i_frame_length_type
==
7
)
)
bs_read
(
&
s
,
2
);
// muxSlotLengthCoded
{
bs_read
(
&
s
,
2
);
// muxSlotLengthCoded
}
else
{
}
}
}
}
for
(
i_chunk
=
0
;
i_chunk
<
i_chunks
;
i_chunk
++
)
for
(
int
i_chunk
=
0
;
i_chunk
<
i_chunks
;
i_chunk
++
)
{
{
//const int i_program = pi_program[i_chunk];
//const int i_program = pi_program[i_chunk];
//const int i_layer = pi_layer[i_chunk];
//const int i_layer = pi_layer[i_chunk];
...
@@ -954,11 +852,11 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
...
@@ -954,11 +852,11 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
}
}
}
}
if
(
p_sys
->
latm
.
i_other_data
>
0
)
#if 0
{
if (p_sys->latm.i_other_data > 0)
/* Other data XXX we just ignore them */
; // TODO
}
#endif
bs_align
(
&
s
);
bs_align
(
&
s
);
return
i_accumulated
;
return
i_accumulated
;
}
}
...
@@ -966,70 +864,64 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
...
@@ -966,70 +864,64 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
/****************************************************************************
/****************************************************************************
* PacketizeStreamBlock: ADTS/LOAS packetizer
* PacketizeStreamBlock: ADTS/LOAS packetizer
****************************************************************************/
****************************************************************************/
static
void
SetupOutput
(
decoder_t
*
p_dec
,
block_t
*
p_block
);
static
void
SetupOutput
(
decoder_t
*
p_dec
,
block_t
*
p_block
);
static
block_t
*
PacketizeStreamBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
static
block_t
*
PacketizeStreamBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
uint8_t
p_header
[
ADTS_HEADER_SIZE
+
LOAS_HEADER_SIZE
];
uint8_t
p_header
[
ADTS_HEADER_SIZE
+
LOAS_HEADER_SIZE
];
block_t
*
p_out_buffer
;
block_t
*
p_out_buffer
;
uint8_t
*
p_buf
;
uint8_t
*
p_buf
;
if
(
!
pp_block
||
!*
pp_block
)
return
NULL
;
if
(
!
pp_block
||
!*
pp_block
)
return
NULL
;
if
(
(
*
pp_block
)
->
i_flags
&
(
BLOCK_FLAG_DISCONTINUITY
|
BLOCK_FLAG_CORRUPTED
)
)
if
((
*
pp_block
)
->
i_flags
&
(
BLOCK_FLAG_DISCONTINUITY
|
BLOCK_FLAG_CORRUPTED
))
{
{
if
((
*
pp_block
)
->
i_flags
&
BLOCK_FLAG_CORRUPTED
)
{
if
(
(
*
pp_block
)
->
i_flags
&
BLOCK_FLAG_CORRUPTED
)
{
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
block_BytestreamEmpty
(
&
p_sys
->
bytestream
);
block_BytestreamEmpty
(
&
p_sys
->
bytestream
);
}
}
date_Set
(
&
p_sys
->
end_date
,
0
);
date_Set
(
&
p_sys
->
end_date
,
0
);
block_Release
(
*
pp_block
);
block_Release
(
*
pp_block
);
return
NULL
;
return
NULL
;
}
}
if
(
!
date_Get
(
&
p_sys
->
end_date
)
&&
(
*
pp_block
)
->
i_pts
<=
VLC_TS_INVALID
)
if
(
!
date_Get
(
&
p_sys
->
end_date
)
&&
(
*
pp_block
)
->
i_pts
<=
VLC_TS_INVALID
)
{
{
/* We've just started the stream, wait for the first PTS. */
/* We've just started the stream, wait for the first PTS. */
block_Release
(
*
pp_block
);
block_Release
(
*
pp_block
);
return
NULL
;
return
NULL
;
}
}
block_BytestreamPush
(
&
p_sys
->
bytestream
,
*
pp_block
);
block_BytestreamPush
(
&
p_sys
->
bytestream
,
*
pp_block
);
for
(
;;
)
for
(;;
)
{
{
switch
(
p_sys
->
i_state
)
switch
(
p_sys
->
i_state
)
{
{
case
STATE_NOSYNC
:
case
STATE_NOSYNC
:
while
(
block_PeekBytes
(
&
p_sys
->
bytestream
,
p_header
,
2
)
while
(
block_PeekBytes
(
&
p_sys
->
bytestream
,
p_header
,
2
)
==
VLC_SUCCESS
)
==
VLC_SUCCESS
)
{
{
/* Look for sync word - should be 0xfff(adts) or 0x2b7(loas) */
/* Look for sync word - should be 0xfff(adts) or 0x2b7(loas) */
if
(
p_header
[
0
]
==
0xff
&&
(
p_header
[
1
]
&
0xf6
)
==
0xf0
)
if
(
p_header
[
0
]
==
0xff
&&
(
p_header
[
1
]
&
0xf6
)
==
0xf0
)
{
{
if
(
p_sys
->
i_type
!=
TYPE_ADTS
)
if
(
p_sys
->
i_type
!=
TYPE_ADTS
)
msg_Dbg
(
p_dec
,
"detected ADTS format"
);
msg_Dbg
(
p_dec
,
"detected ADTS format"
);
p_sys
->
i_state
=
STATE_SYNC
;
p_sys
->
i_state
=
STATE_SYNC
;
p_sys
->
i_type
=
TYPE_ADTS
;
p_sys
->
i_type
=
TYPE_ADTS
;
break
;
break
;
}
}
else
if
(
p_header
[
0
]
==
0x56
&&
(
p_header
[
1
]
&
0xe0
)
==
0xe0
)
{
else
if
(
p_header
[
0
]
==
0x56
&&
(
p_header
[
1
]
&
0xe0
)
==
0xe0
)
if
(
p_sys
->
i_type
!=
TYPE_LOAS
)
{
msg_Dbg
(
p_dec
,
"detected LOAS format"
);
if
(
p_sys
->
i_type
!=
TYPE_LOAS
)
msg_Dbg
(
p_dec
,
"detected LOAS format"
);
p_sys
->
i_state
=
STATE_SYNC
;
p_sys
->
i_state
=
STATE_SYNC
;
p_sys
->
i_type
=
TYPE_LOAS
;
p_sys
->
i_type
=
TYPE_LOAS
;
break
;
break
;
}
}
block_SkipByte
(
&
p_sys
->
bytestream
);
block_SkipByte
(
&
p_sys
->
bytestream
);
}
}
if
(
p_sys
->
i_state
!=
STATE_SYNC
)
if
(
p_sys
->
i_state
!=
STATE_SYNC
)
{
{
block_BytestreamFlush
(
&
p_sys
->
bytestream
);
block_BytestreamFlush
(
&
p_sys
->
bytestream
);
/* Need more data */
/* Need more data */
return
NULL
;
return
NULL
;
...
@@ -1038,51 +930,39 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -1038,51 +930,39 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
case
STATE_SYNC
:
case
STATE_SYNC
:
/* New frame, set the Presentation Time Stamp */
/* New frame, set the Presentation Time Stamp */
p_sys
->
i_pts
=
p_sys
->
bytestream
.
p_block
->
i_pts
;
p_sys
->
i_pts
=
p_sys
->
bytestream
.
p_block
->
i_pts
;
if
(
p_sys
->
i_pts
>
VLC_TS_INVALID
&&
if
(
p_sys
->
i_pts
>
VLC_TS_INVALID
&&
p_sys
->
i_pts
!=
date_Get
(
&
p_sys
->
end_date
)
)
p_sys
->
i_pts
!=
date_Get
(
&
p_sys
->
end_date
))
{
date_Set
(
&
p_sys
->
end_date
,
p_sys
->
i_pts
);
date_Set
(
&
p_sys
->
end_date
,
p_sys
->
i_pts
);
}
p_sys
->
i_state
=
STATE_HEADER
;
p_sys
->
i_state
=
STATE_HEADER
;
break
;
break
;
case
STATE_HEADER
:
case
STATE_HEADER
:
if
(
p_sys
->
i_type
==
TYPE_ADTS
)
if
(
p_sys
->
i_type
==
TYPE_ADTS
)
{
{
/* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */
/* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */
if
(
block_PeekBytes
(
&
p_sys
->
bytestream
,
p_header
,
if
(
block_PeekBytes
(
&
p_sys
->
bytestream
,
p_header
,
ADTS_HEADER_SIZE
)
!=
VLC_SUCCESS
)
ADTS_HEADER_SIZE
)
!=
VLC_SUCCESS
)
{
return
NULL
;
/* Need more data */
/* Need more data */
return
NULL
;
}
/* Check if frame is valid and get frame info */
/* Check if frame is valid and get frame info */
p_sys
->
i_frame_size
=
ADTSSyncInfo
(
p_dec
,
p_header
,
p_sys
->
i_frame_size
=
ADTSSyncInfo
(
p_dec
,
p_header
,
&
p_sys
->
i_channels
,
&
p_sys
->
i_channels
,
&
p_sys
->
i_rate
,
&
p_sys
->
i_rate
,
&
p_sys
->
i_frame_length
,
&
p_sys
->
i_frame_length
,
&
p_sys
->
i_header_size
);
&
p_sys
->
i_header_size
);
}
}
else
{
else
assert
(
p_sys
->
i_type
==
TYPE_LOAS
);
{
assert
(
p_sys
->
i_type
==
TYPE_LOAS
);
/* Get LOAS frame header (LOAS_HEADER_SIZE bytes) */
/* Get LOAS frame header (LOAS_HEADER_SIZE bytes) */
if
(
block_PeekBytes
(
&
p_sys
->
bytestream
,
p_header
,
if
(
block_PeekBytes
(
&
p_sys
->
bytestream
,
p_header
,
LOAS_HEADER_SIZE
)
!=
VLC_SUCCESS
)
LOAS_HEADER_SIZE
)
!=
VLC_SUCCESS
)
{
return
NULL
;
/* Need more data */
/* Need more data */
return
NULL
;
}
/* Check if frame is valid and get frame info */
/* Check if frame is valid and get frame info */
p_sys
->
i_frame_size
=
LOASSyncInfo
(
p_header
,
&
p_sys
->
i_header_size
);
p_sys
->
i_frame_size
=
LOASSyncInfo
(
p_header
,
&
p_sys
->
i_header_size
);
}
}
if
(
p_sys
->
i_frame_size
<=
0
)
if
(
p_sys
->
i_frame_size
<=
0
)
{
{
msg_Dbg
(
p_dec
,
"emulated sync word"
);
msg_Dbg
(
p_dec
,
"emulated sync word"
);
block_SkipByte
(
&
p_sys
->
bytestream
);
block_SkipByte
(
&
p_sys
->
bytestream
);
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
break
;
break
;
}
}
...
@@ -1092,32 +972,26 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -1092,32 +972,26 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
case
STATE_NEXT_SYNC
:
case
STATE_NEXT_SYNC
:
/* TODO: If p_block == NULL, flush the buffer without checking the
/* TODO: If p_block == NULL, flush the buffer without checking the
* next sync word */
* next sync word */
if
(
p_sys
->
bytestream
.
p_block
==
NULL
)
if
(
p_sys
->
bytestream
.
p_block
==
NULL
)
{
{
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
block_BytestreamFlush
(
&
p_sys
->
bytestream
);
block_BytestreamFlush
(
&
p_sys
->
bytestream
);
return
NULL
;
return
NULL
;
}
}
/* Check if next expected frame contains the sync word */
/* Check if next expected frame contains the sync word */
if
(
block_PeekOffsetBytes
(
&
p_sys
->
bytestream
,
p_sys
->
i_frame_size
if
(
block_PeekOffsetBytes
(
&
p_sys
->
bytestream
,
p_sys
->
i_frame_size
+
p_sys
->
i_header_size
,
p_header
,
2
)
+
p_sys
->
i_header_size
,
p_header
,
2
)
!=
VLC_SUCCESS
)
!=
VLC_SUCCESS
)
return
NULL
;
/* Need more data */
{
/* Need more data */
assert
((
p_sys
->
i_type
==
TYPE_ADTS
)
||
(
p_sys
->
i_type
==
TYPE_LOAS
));
return
NULL
;
if
(((
p_sys
->
i_type
==
TYPE_ADTS
)
&&
}
(
p_header
[
0
]
!=
0xff
||
(
p_header
[
1
]
&
0xf6
)
!=
0xf0
))
||
((
p_sys
->
i_type
==
TYPE_LOAS
)
&&
assert
(
(
p_sys
->
i_type
==
TYPE_ADTS
)
||
(
p_sys
->
i_type
==
TYPE_LOAS
)
);
(
p_header
[
0
]
!=
0x56
||
(
p_header
[
1
]
&
0xe0
)
!=
0xe0
)))
{
if
(
(
(
p_sys
->
i_type
==
TYPE_ADTS
)
&&
msg_Dbg
(
p_dec
,
"emulated sync word "
(
p_header
[
0
]
!=
0xff
||
(
p_header
[
1
]
&
0xf6
)
!=
0xf0
)
)
||
"(no sync on following frame)"
);
(
(
p_sys
->
i_type
==
TYPE_LOAS
)
&&
(
p_header
[
0
]
!=
0x56
||
(
p_header
[
1
]
&
0xe0
)
!=
0xe0
)
)
)
{
msg_Dbg
(
p_dec
,
"emulated sync word "
"(no sync on following frame)"
);
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
block_SkipByte
(
&
p_sys
->
bytestream
);
block_SkipByte
(
&
p_sys
->
bytestream
);
break
;
break
;
}
}
...
@@ -1127,58 +1001,50 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -1127,58 +1001,50 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
case
STATE_GET_DATA
:
case
STATE_GET_DATA
:
/* Make sure we have enough data.
/* Make sure we have enough data.
* (Not useful if we went through NEXT_SYNC) */
* (Not useful if we went through NEXT_SYNC) */
if
(
block_WaitBytes
(
&
p_sys
->
bytestream
,
p_sys
->
i_frame_size
+
if
(
block_WaitBytes
(
&
p_sys
->
bytestream
,
p_sys
->
i_frame_size
+
p_sys
->
i_header_size
)
!=
VLC_SUCCESS
)
p_sys
->
i_header_size
)
!=
VLC_SUCCESS
)
{
return
NULL
;
/* Need more data */
/* Need more data */
return
NULL
;
}
p_sys
->
i_state
=
STATE_SEND_DATA
;
p_sys
->
i_state
=
STATE_SEND_DATA
;
case
STATE_SEND_DATA
:
case
STATE_SEND_DATA
:
/* When we reach this point we already know we have enough
/* When we reach this point we already know we have enough
* data available. */
* data available. */
p_out_buffer
=
block_Alloc
(
p_sys
->
i_frame_size
);
p_out_buffer
=
block_Alloc
(
p_sys
->
i_frame_size
);
if
(
!
p_out_buffer
)
if
(
!
p_out_buffer
)
{
{
//p_dec->b_error = true;
//p_dec->b_error = true;
return
NULL
;
return
NULL
;
}
}
p_buf
=
p_out_buffer
->
p_buffer
;
p_buf
=
p_out_buffer
->
p_buffer
;
/* Skip the ADTS/LOAS header */
/* Skip the ADTS/LOAS header */
block_SkipBytes
(
&
p_sys
->
bytestream
,
p_sys
->
i_header_size
);
block_SkipBytes
(
&
p_sys
->
bytestream
,
p_sys
->
i_header_size
);
if
(
p_sys
->
i_type
==
TYPE_ADTS
)
if
(
p_sys
->
i_type
==
TYPE_ADTS
)
{
{
/* Copy the whole frame into the buffer */
/* Copy the whole frame into the buffer */
block_GetBytes
(
&
p_sys
->
bytestream
,
p_buf
,
p_sys
->
i_frame_size
);
block_GetBytes
(
&
p_sys
->
bytestream
,
p_buf
,
p_sys
->
i_frame_size
);
}
}
else
{
else
assert
(
p_sys
->
i_type
==
TYPE_LOAS
);
{
assert
(
p_sys
->
i_type
==
TYPE_LOAS
);
/* Copy the whole frame into the buffer and parse/extract it */
/* Copy the whole frame into the buffer and parse/extract it */
block_GetBytes
(
&
p_sys
->
bytestream
,
p_buf
,
p_sys
->
i_frame_size
);
block_GetBytes
(
&
p_sys
->
bytestream
,
p_buf
,
p_sys
->
i_frame_size
);
p_out_buffer
->
i_buffer
=
LOASParse
(
p_dec
,
p_buf
,
p_sys
->
i_frame_size
);
p_out_buffer
->
i_buffer
=
LOASParse
(
p_dec
,
p_buf
,
p_sys
->
i_frame_size
);
if
(
p_out_buffer
->
i_buffer
<=
0
)
if
(
p_out_buffer
->
i_buffer
<=
0
)
{
{
if
(
!
p_sys
->
b_latm_cfg
)
if
(
!
p_sys
->
b_latm_cfg
)
msg_Warn
(
p_dec
,
"waiting for header"
);
msg_Warn
(
p_dec
,
"waiting for header"
);
block_Release
(
p_out_buffer
);
block_Release
(
p_out_buffer
);
p_out_buffer
=
NULL
;
p_out_buffer
=
NULL
;
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
break
;
break
;
}
}
}
}
SetupOutput
(
p_dec
,
p_out_buffer
);
SetupOutput
(
p_dec
,
p_out_buffer
);
/* Make sure we don't reuse the same pts twice */
/* Make sure we don't reuse the same pts twice */
if
(
p_sys
->
i_pts
==
p_sys
->
bytestream
.
p_block
->
i_pts
)
if
(
p_sys
->
i_pts
==
p_sys
->
bytestream
.
p_block
->
i_pts
)
p_sys
->
i_pts
=
p_sys
->
bytestream
.
p_block
->
i_pts
=
VLC_TS_INVALID
;
p_sys
->
i_pts
=
p_sys
->
bytestream
.
p_block
->
i_pts
=
VLC_TS_INVALID
;
/* So p_block doesn't get re-added several times */
/* So p_block doesn't get re-added several times */
*
pp_block
=
block_BytestreamPop
(
&
p_sys
->
bytestream
);
*
pp_block
=
block_BytestreamPop
(
&
p_sys
->
bytestream
);
p_sys
->
i_state
=
STATE_NOSYNC
;
p_sys
->
i_state
=
STATE_NOSYNC
;
...
@@ -1192,18 +1058,17 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -1192,18 +1058,17 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
/*****************************************************************************
/*****************************************************************************
* SetupBuffer:
* SetupBuffer:
*****************************************************************************/
*****************************************************************************/
static
void
SetupOutput
(
decoder_t
*
p_dec
,
block_t
*
p_block
)
static
void
SetupOutput
(
decoder_t
*
p_dec
,
block_t
*
p_block
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
if
(
p_dec
->
fmt_out
.
audio
.
i_rate
!=
p_sys
->
i_rate
)
if
(
p_dec
->
fmt_out
.
audio
.
i_rate
!=
p_sys
->
i_rate
)
{
{
msg_Info
(
p_dec
,
"AAC channels: %d samplerate: %d"
,
msg_Info
(
p_dec
,
"AAC channels: %d samplerate: %d"
,
p_sys
->
i_channels
,
p_sys
->
i_rate
);
p_sys
->
i_channels
,
p_sys
->
i_rate
);
const
mtime_t
i_end_date
=
date_Get
(
&
p_sys
->
end_date
);
const
mtime_t
i_end_date
=
date_Get
(
&
p_sys
->
end_date
);
date_Init
(
&
p_sys
->
end_date
,
p_sys
->
i_rate
,
1
);
date_Init
(
&
p_sys
->
end_date
,
p_sys
->
i_rate
,
1
);
date_Set
(
&
p_sys
->
end_date
,
i_end_date
);
date_Set
(
&
p_sys
->
end_date
,
i_end_date
);
}
}
p_dec
->
fmt_out
.
audio
.
i_rate
=
p_sys
->
i_rate
;
p_dec
->
fmt_out
.
audio
.
i_rate
=
p_sys
->
i_rate
;
...
@@ -1216,21 +1081,21 @@ static void SetupOutput( decoder_t *p_dec, block_t *p_block )
...
@@ -1216,21 +1081,21 @@ static void SetupOutput( decoder_t *p_dec, block_t *p_block )
p_dec->fmt_out.audio.i_physical_channels = p_sys->i_channels_conf;
p_dec->fmt_out.audio.i_physical_channels = p_sys->i_channels_conf;
#endif
#endif
p_block
->
i_pts
=
p_block
->
i_dts
=
date_Get
(
&
p_sys
->
end_date
);
p_block
->
i_pts
=
p_block
->
i_dts
=
date_Get
(
&
p_sys
->
end_date
);
p_block
->
i_length
=
p_block
->
i_length
=
date_Increment
(
&
p_sys
->
end_date
,
p_sys
->
i_frame_length
)
-
p_block
->
i_pts
;
date_Increment
(
&
p_sys
->
end_date
,
p_sys
->
i_frame_length
)
-
p_block
->
i_pts
;
}
}
/*****************************************************************************
/*****************************************************************************
* ClosePacketizer: clean up the packetizer
* ClosePacketizer: clean up the packetizer
*****************************************************************************/
*****************************************************************************/
static
void
ClosePacketizer
(
vlc_object_t
*
p_this
)
static
void
ClosePacketizer
(
vlc_object_t
*
p_this
)
{
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_BytestreamRelease
(
&
p_sys
->
bytestream
);
block_BytestreamRelease
(
&
p_sys
->
bytestream
);
free
(
p_dec
->
p_sys
);
free
(
p_dec
->
p_sys
);
}
}
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