Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
3f1a38c9
Commit
3f1a38c9
authored
Feb 09, 2017
by
Alex Converse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
aac_latm: Allow unaligned AudioSpecificConfig
Fixes ticket 4730
parent
8a3fea14
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
120 additions
and
76 deletions
+120
-76
aacdec.c
libavcodec/aacdec.c
+15
-11
aacdec_template.c
libavcodec/aacdec_template.c
+52
-30
mpeg4audio.c
libavcodec/mpeg4audio.c
+42
-34
mpeg4audio.h
libavcodec/mpeg4audio.h
+11
-1
No files found.
libavcodec/aacdec.c
View file @
3f1a38c9
...
...
@@ -284,9 +284,10 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
AACContext
*
ac
=
&
latmctx
->
aac_ctx
;
AVCodecContext
*
avctx
=
ac
->
avctx
;
MPEG4AudioConfig
m4ac
=
{
0
};
GetBitContext
gbc
;
int
config_start_bit
=
get_bits_count
(
gb
);
int
sync_extension
=
0
;
int
bits_consumed
,
esize
;
int
bits_consumed
,
esize
,
i
;
if
(
asclen
)
{
sync_extension
=
1
;
...
...
@@ -294,19 +295,19 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
}
else
asclen
=
get_bits_left
(
gb
);
if
(
config_start_bit
%
8
)
{
avpriv_request_sample
(
latmctx
->
aac_ctx
.
avctx
,
"Non-byte-aligned audio-specific config"
);
return
AVERROR_PATCHWELCOME
;
}
if
(
asclen
<=
0
)
return
AVERROR_INVALIDDATA
;
bits_consumed
=
decode_audio_specific_config
(
NULL
,
avctx
,
&
m4ac
,
gb
->
buffer
+
(
config_start_bit
/
8
),
asclen
,
sync_extension
);
if
(
bits_consumed
<
0
)
init_get_bits
(
&
gbc
,
gb
->
buffer
,
config_start_bit
+
asclen
);
skip_bits_long
(
&
gbc
,
config_start_bit
);
bits_consumed
=
decode_audio_specific_config_gb
(
NULL
,
avctx
,
&
m4ac
,
&
gbc
,
config_start_bit
,
sync_extension
);
if
(
bits_consumed
<
config_start_bit
)
return
AVERROR_INVALIDDATA
;
bits_consumed
-=
config_start_bit
;
if
(
!
latmctx
->
initialized
||
ac
->
oc
[
1
].
m4ac
.
sample_rate
!=
m4ac
.
sample_rate
||
...
...
@@ -329,7 +330,10 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
}
avctx
->
extradata_size
=
esize
;
memcpy
(
avctx
->
extradata
,
gb
->
buffer
+
(
config_start_bit
/
8
),
esize
);
gbc
=
*
gb
;
for
(
i
=
0
;
i
<
esize
;
i
++
)
{
avctx
->
extradata
[
i
]
=
get_bits
(
&
gbc
,
8
);
}
memset
(
avctx
->
extradata
+
esize
,
0
,
AV_INPUT_BUFFER_PADDING_SIZE
);
}
skip_bits_long
(
gb
,
bits_consumed
);
...
...
libavcodec/aacdec_template.c
View file @
3f1a38c9
...
...
@@ -715,6 +715,13 @@ static void decode_channel_map(uint8_t layout_map[][3],
}
}
static
inline
void
relative_align_get_bits
(
GetBitContext
*
gb
,
int
reference_position
)
{
int
n
=
(
reference_position
-
get_bits_count
(
gb
)
&
7
);
if
(
n
)
skip_bits
(
gb
,
n
);
}
/**
* Decode program configuration element; reference: table 4.2.
*
...
...
@@ -722,7 +729,7 @@ static void decode_channel_map(uint8_t layout_map[][3],
*/
static
int
decode_pce
(
AVCodecContext
*
avctx
,
MPEG4AudioConfig
*
m4ac
,
uint8_t
(
*
layout_map
)[
3
],
GetBitContext
*
gb
)
GetBitContext
*
gb
,
int
byte_align_ref
)
{
int
num_front
,
num_side
,
num_back
,
num_lfe
,
num_assoc_data
,
num_cc
;
int
sampling_index
;
...
...
@@ -770,7 +777,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
decode_channel_map
(
layout_map
+
tags
,
AAC_CHANNEL_CC
,
gb
,
num_cc
);
tags
+=
num_cc
;
align_get_bits
(
gb
);
relative_align_get_bits
(
gb
,
byte_align_ref
);
/* comment field, first byte is length */
comment_len
=
get_bits
(
gb
,
8
)
*
8
;
...
...
@@ -792,6 +799,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
*/
static
int
decode_ga_specific_config
(
AACContext
*
ac
,
AVCodecContext
*
avctx
,
GetBitContext
*
gb
,
int
get_bit_alignment
,
MPEG4AudioConfig
*
m4ac
,
int
channel_config
)
{
...
...
@@ -815,7 +823,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
if
(
channel_config
==
0
)
{
skip_bits
(
gb
,
4
);
// element_instance_tag
tags
=
decode_pce
(
avctx
,
m4ac
,
layout_map
,
gb
);
tags
=
decode_pce
(
avctx
,
m4ac
,
layout_map
,
gb
,
get_bit_alignment
);
if
(
tags
<
0
)
return
tags
;
}
else
{
...
...
@@ -937,37 +945,25 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
* @param ac pointer to AACContext, may be null
* @param avctx pointer to AVCCodecContext, used for logging
* @param m4ac pointer to MPEG4AudioConfig, used for parsing
* @param
data pointer to
buffer holding an audio specific config
* @param
bit_size size of audio specific config or data in bit
s
* @param
gb
buffer holding an audio specific config
* @param
get_bit_alignment relative alignment for byte align operation
s
* @param sync_extension look for an appended sync extension
*
* @return Returns error status or number of consumed bits. <0 - error
*/
static
int
decode_audio_specific_config
(
AACContext
*
ac
,
static
int
decode_audio_specific_config
_gb
(
AACContext
*
ac
,
AVCodecContext
*
avctx
,
MPEG4AudioConfig
*
m4ac
,
const
uint8_t
*
data
,
int64_t
bit_size
,
GetBitContext
*
gb
,
int
get_bit_alignment
,
int
sync_extension
)
{
GetBitContext
gb
;
int
i
,
ret
;
GetBitContext
gbc
=
*
gb
;
if
(
bit_size
<
0
||
bit_size
>
INT_MAX
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Audio specific config size is invalid
\n
"
);
if
((
i
=
ff_mpeg4audio_get_config_gb
(
m4ac
,
&
gbc
,
sync_extension
))
<
0
)
return
AVERROR_INVALIDDATA
;
}
ff_dlog
(
avctx
,
"audio specific config size %d
\n
"
,
(
int
)
bit_size
>>
3
);
for
(
i
=
0
;
i
<
bit_size
>>
3
;
i
++
)
ff_dlog
(
avctx
,
"%02x "
,
data
[
i
]);
ff_dlog
(
avctx
,
"
\n
"
);
if
((
ret
=
init_get_bits
(
&
gb
,
data
,
bit_size
))
<
0
)
return
ret
;
if
((
i
=
avpriv_mpeg4audio_get_config
(
m4ac
,
data
,
bit_size
,
sync_extension
))
<
0
)
return
AVERROR_INVALIDDATA
;
if
(
m4ac
->
sampling_index
>
12
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid sampling rate index %d
\n
"
,
...
...
@@ -982,7 +978,7 @@ static int decode_audio_specific_config(AACContext *ac,
return
AVERROR_INVALIDDATA
;
}
skip_bits_long
(
&
gb
,
i
);
skip_bits_long
(
gb
,
i
);
switch
(
m4ac
->
object_type
)
{
case
AOT_AAC_MAIN
:
...
...
@@ -990,12 +986,12 @@ static int decode_audio_specific_config(AACContext *ac,
case
AOT_AAC_LTP
:
case
AOT_ER_AAC_LC
:
case
AOT_ER_AAC_LD
:
if
((
ret
=
decode_ga_specific_config
(
ac
,
avctx
,
&
gb
,
if
((
ret
=
decode_ga_specific_config
(
ac
,
avctx
,
gb
,
get_bit_alignment
,
m4ac
,
m4ac
->
chan_config
))
<
0
)
return
ret
;
break
;
case
AOT_ER_AAC_ELD
:
if
((
ret
=
decode_eld_specific_config
(
ac
,
avctx
,
&
gb
,
if
((
ret
=
decode_eld_specific_config
(
ac
,
avctx
,
gb
,
m4ac
,
m4ac
->
chan_config
))
<
0
)
return
ret
;
break
;
...
...
@@ -1013,7 +1009,33 @@ static int decode_audio_specific_config(AACContext *ac,
m4ac
->
sample_rate
,
m4ac
->
sbr
,
m4ac
->
ps
);
return
get_bits_count
(
&
gb
);
return
get_bits_count
(
gb
);
}
static
int
decode_audio_specific_config
(
AACContext
*
ac
,
AVCodecContext
*
avctx
,
MPEG4AudioConfig
*
m4ac
,
const
uint8_t
*
data
,
int64_t
bit_size
,
int
sync_extension
)
{
int
i
,
ret
;
GetBitContext
gb
;
if
(
bit_size
<
0
||
bit_size
>
INT_MAX
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Audio specific config size is invalid
\n
"
);
return
AVERROR_INVALIDDATA
;
}
ff_dlog
(
avctx
,
"audio specific config size %d
\n
"
,
(
int
)
bit_size
>>
3
);
for
(
i
=
0
;
i
<
bit_size
>>
3
;
i
++
)
ff_dlog
(
avctx
,
"%02x "
,
data
[
i
]);
ff_dlog
(
avctx
,
"
\n
"
);
if
((
ret
=
init_get_bits
(
&
gb
,
data
,
bit_size
))
<
0
)
return
ret
;
return
decode_audio_specific_config_gb
(
ac
,
avctx
,
m4ac
,
&
gb
,
0
,
sync_extension
);
}
/**
...
...
@@ -3003,7 +3025,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
uint8_t
layout_map
[
MAX_ELEM_ID
*
4
][
3
];
int
tags
;
push_output_configuration
(
ac
);
tags
=
decode_pce
(
avctx
,
&
ac
->
oc
[
1
].
m4ac
,
layout_map
,
gb
);
tags
=
decode_pce
(
avctx
,
&
ac
->
oc
[
1
].
m4ac
,
layout_map
,
gb
,
0
);
if
(
tags
<
0
)
{
err
=
tags
;
break
;
...
...
libavcodec/mpeg4audio.c
View file @
3f1a38c9
...
...
@@ -83,70 +83,62 @@ static inline int get_sample_rate(GetBitContext *gb, int *index)
avpriv_mpeg4audio_sample_rates
[
*
index
];
}
int
avpriv_mpeg4audio_get_config
(
MPEG4AudioConfig
*
c
,
const
uint8_t
*
buf
,
int
bit_size
,
int
sync_extension
)
int
ff_mpeg4audio_get_config_gb
(
MPEG4AudioConfig
*
c
,
GetBitContext
*
gb
,
int
sync_extension
)
{
GetBitContext
gb
;
int
specific_config_bitindex
,
ret
;
if
(
bit_size
<=
0
)
return
AVERROR_INVALIDDATA
;
ret
=
init_get_bits
(
&
gb
,
buf
,
bit_size
);
if
(
ret
<
0
)
return
ret
;
c
->
object_type
=
get_object_type
(
&
gb
);
c
->
sample_rate
=
get_sample_rate
(
&
gb
,
&
c
->
sampling_index
);
c
->
chan_config
=
get_bits
(
&
gb
,
4
);
int
start_bit_index
=
get_bits_count
(
gb
);
c
->
object_type
=
get_object_type
(
gb
);
c
->
sample_rate
=
get_sample_rate
(
gb
,
&
c
->
sampling_index
);
c
->
chan_config
=
get_bits
(
gb
,
4
);
if
(
c
->
chan_config
<
FF_ARRAY_ELEMS
(
ff_mpeg4audio_channels
))
c
->
channels
=
ff_mpeg4audio_channels
[
c
->
chan_config
];
c
->
sbr
=
-
1
;
c
->
ps
=
-
1
;
if
(
c
->
object_type
==
AOT_SBR
||
(
c
->
object_type
==
AOT_PS
&&
// check for W6132 Annex YYYY draft MP3onMP4
!
(
show_bits
(
&
gb
,
3
)
&
0x03
&&
!
(
show_bits
(
&
gb
,
9
)
&
0x3F
))))
{
!
(
show_bits
(
gb
,
3
)
&
0x03
&&
!
(
show_bits
(
gb
,
9
)
&
0x3F
))))
{
if
(
c
->
object_type
==
AOT_PS
)
c
->
ps
=
1
;
c
->
ext_object_type
=
AOT_SBR
;
c
->
sbr
=
1
;
c
->
ext_sample_rate
=
get_sample_rate
(
&
gb
,
&
c
->
ext_sampling_index
);
c
->
object_type
=
get_object_type
(
&
gb
);
c
->
ext_sample_rate
=
get_sample_rate
(
gb
,
&
c
->
ext_sampling_index
);
c
->
object_type
=
get_object_type
(
gb
);
if
(
c
->
object_type
==
AOT_ER_BSAC
)
c
->
ext_chan_config
=
get_bits
(
&
gb
,
4
);
c
->
ext_chan_config
=
get_bits
(
gb
,
4
);
}
else
{
c
->
ext_object_type
=
AOT_NULL
;
c
->
ext_sample_rate
=
0
;
}
specific_config_bitindex
=
get_bits_count
(
&
gb
);
specific_config_bitindex
=
get_bits_count
(
gb
);
if
(
c
->
object_type
==
AOT_ALS
)
{
skip_bits
(
&
gb
,
5
);
if
(
show_bits_long
(
&
gb
,
24
)
!=
MKBETAG
(
'\0'
,
'A'
,
'L'
,
'S'
))
skip_bits_long
(
&
gb
,
24
);
skip_bits
(
gb
,
5
);
if
(
show_bits_long
(
gb
,
24
)
!=
MKBETAG
(
'\0'
,
'A'
,
'L'
,
'S'
))
skip_bits_long
(
gb
,
24
);
specific_config_bitindex
=
get_bits_count
(
&
gb
);
specific_config_bitindex
=
get_bits_count
(
gb
);
ret
=
parse_config_ALS
(
&
gb
,
c
);
ret
=
parse_config_ALS
(
gb
,
c
);
if
(
ret
<
0
)
return
ret
;
}
if
(
c
->
ext_object_type
!=
AOT_SBR
&&
sync_extension
)
{
while
(
get_bits_left
(
&
gb
)
>
15
)
{
if
(
show_bits
(
&
gb
,
11
)
==
0x2b7
)
{
// sync extension
get_bits
(
&
gb
,
11
);
c
->
ext_object_type
=
get_object_type
(
&
gb
);
if
(
c
->
ext_object_type
==
AOT_SBR
&&
(
c
->
sbr
=
get_bits1
(
&
gb
))
==
1
)
{
c
->
ext_sample_rate
=
get_sample_rate
(
&
gb
,
&
c
->
ext_sampling_index
);
while
(
get_bits_left
(
gb
)
>
15
)
{
if
(
show_bits
(
gb
,
11
)
==
0x2b7
)
{
// sync extension
get_bits
(
gb
,
11
);
c
->
ext_object_type
=
get_object_type
(
gb
);
if
(
c
->
ext_object_type
==
AOT_SBR
&&
(
c
->
sbr
=
get_bits1
(
gb
))
==
1
)
{
c
->
ext_sample_rate
=
get_sample_rate
(
gb
,
&
c
->
ext_sampling_index
);
if
(
c
->
ext_sample_rate
==
c
->
sample_rate
)
c
->
sbr
=
-
1
;
}
if
(
get_bits_left
(
&
gb
)
>
11
&&
get_bits
(
&
gb
,
11
)
==
0x548
)
c
->
ps
=
get_bits1
(
&
gb
);
if
(
get_bits_left
(
gb
)
>
11
&&
get_bits
(
gb
,
11
)
==
0x548
)
c
->
ps
=
get_bits1
(
gb
);
break
;
}
else
get_bits1
(
&
gb
);
// skip 1 bit
get_bits1
(
gb
);
// skip 1 bit
}
}
...
...
@@ -157,7 +149,23 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
if
((
c
->
ps
==
-
1
&&
c
->
object_type
!=
AOT_AAC_LC
)
||
c
->
channels
&
~
0x01
)
c
->
ps
=
0
;
return
specific_config_bitindex
;
return
specific_config_bitindex
-
start_bit_index
;
}
int
avpriv_mpeg4audio_get_config
(
MPEG4AudioConfig
*
c
,
const
uint8_t
*
buf
,
int
bit_size
,
int
sync_extension
)
{
GetBitContext
gb
;
int
ret
;
if
(
bit_size
<=
0
)
return
AVERROR_INVALIDDATA
;
ret
=
init_get_bits
(
&
gb
,
buf
,
bit_size
);
if
(
ret
<
0
)
return
ret
;
return
ff_mpeg4audio_get_config_gb
(
c
,
&
gb
,
sync_extension
);
}
static
av_always_inline
unsigned
int
copy_bits
(
PutBitContext
*
pb
,
...
...
libavcodec/mpeg4audio.h
View file @
3f1a38c9
...
...
@@ -45,7 +45,17 @@ extern av_export const int avpriv_mpeg4audio_sample_rates[16];
extern
const
uint8_t
ff_mpeg4audio_channels
[
8
];
/**
* Parse MPEG-4 systems extradata to retrieve audio configuration.
* Parse MPEG-4 systems extradata from a potentially unaligned GetBitContext to retrieve audio configuration.
* @param[in] c MPEG4AudioConfig structure to fill.
* @param[in] gb Extradata from container.
* @param[in] sync_extension look for a sync extension after config if true.
* @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata.
*/
int
ff_mpeg4audio_get_config_gb
(
MPEG4AudioConfig
*
c
,
GetBitContext
*
gb
,
int
sync_extension
);
/**
* Parse MPEG-4 systems extradata from a raw buffer to retrieve audio configuration.
* @param[in] c MPEG4AudioConfig structure to fill.
* @param[in] buf Extradata from container.
* @param[in] bit_size Extradata size in bits.
...
...
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