Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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
Hide 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
,
AVCodecContext
*
avctx
,
MPEG4AudioConfig
*
m4ac
,
const
uint8_t
*
data
,
int64_t
bit_size
,
int
sync_extension
)
static
int
decode_audio_specific_config_gb
(
AACContext
*
ac
,
AVCodecContext
*
avctx
,
MPEG4AudioConfig
*
m4ac
,
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