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
b8c2b9c3
Commit
b8c2b9c3
authored
Feb 20, 2017
by
Daniil Cherednik
Committed by
Rostislav Pehlivanov
May 08, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avcodec/dcaenc: Initial implementation of ADPCM encoding for DCA encoder
parent
5f928c52
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
546 additions
and
76 deletions
+546
-76
Makefile
libavcodec/Makefile
+2
-1
dca_core.c
libavcodec/dca_core.c
+11
-35
dca_core.h
libavcodec/dca_core.h
+24
-1
dcaadpcm.c
libavcodec/dcaadpcm.c
+228
-0
dcaadpcm.h
libavcodec/dcaadpcm.h
+54
-0
dcadata.c
libavcodec/dcadata.c
+1
-1
dcadata.h
libavcodec/dcadata.h
+4
-1
dcaenc.c
libavcodec/dcaenc.c
+210
-37
dcaenc.h
libavcodec/dcaenc.h
+11
-0
dcamath.h
libavcodec/dcamath.h
+1
-0
No files found.
libavcodec/Makefile
View file @
b8c2b9c3
...
@@ -244,7 +244,8 @@ OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
...
@@ -244,7 +244,8 @@ OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
OBJS-$(CONFIG_DCA_DECODER)
+=
dcadec.o
dca.o
dcadata.o
dcahuff.o
\
OBJS-$(CONFIG_DCA_DECODER)
+=
dcadec.o
dca.o
dcadata.o
dcahuff.o
\
dca_core.o
dca_exss.o
dca_xll.o
dca_lbr.o
\
dca_core.o
dca_exss.o
dca_xll.o
dca_lbr.o
\
dcadsp.o
dcadct.o
synth_filter.o
dcadsp.o
dcadct.o
synth_filter.o
OBJS-$(CONFIG_DCA_ENCODER)
+=
dcaenc.o
dca.o
dcadata.o
dcahuff.o
OBJS-$(CONFIG_DCA_ENCODER)
+=
dcaenc.o
dca.o
dcadata.o
dcahuff.o
\
dcaadpcm.o
OBJS-$(CONFIG_DDS_DECODER)
+=
dds.o
OBJS-$(CONFIG_DDS_DECODER)
+=
dds.o
OBJS-$(CONFIG_DIRAC_DECODER)
+=
diracdec.o
dirac.o
diracdsp.o
diractab.o
\
OBJS-$(CONFIG_DIRAC_DECODER)
+=
diracdec.o
dirac.o
diracdsp.o
diractab.o
\
dirac_arith.o
dirac_dwt.o
dirac_vlc.o
dirac_arith.o
dirac_dwt.o
dirac_vlc.o
...
...
libavcodec/dca_core.c
View file @
b8c2b9c3
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
#include "dcaadpcm.h"
#include "dcadec.h"
#include "dcadec.h"
#include "dcadata.h"
#include "dcadata.h"
#include "dcahuff.h"
#include "dcahuff.h"
...
@@ -670,46 +671,21 @@ static inline int extract_audio(DCACoreDecoder *s, int32_t *audio, int abits, in
...
@@ -670,46 +671,21 @@ static inline int extract_audio(DCACoreDecoder *s, int32_t *audio, int abits, in
return
0
;
return
0
;
}
}
static
inline
void
dequantize
(
int32_t
*
output
,
const
int32_t
*
input
,
int32_t
step_size
,
int32_t
scale
,
int
residual
)
{
// Account for quantizer step size
int64_t
step_scale
=
(
int64_t
)
step_size
*
scale
;
int
n
,
shift
=
0
;
// Limit scale factor resolution to 22 bits
if
(
step_scale
>
(
1
<<
23
))
{
shift
=
av_log2
(
step_scale
>>
23
)
+
1
;
step_scale
>>=
shift
;
}
// Scale the samples
if
(
residual
)
{
for
(
n
=
0
;
n
<
DCA_SUBBAND_SAMPLES
;
n
++
)
output
[
n
]
+=
clip23
(
norm__
(
input
[
n
]
*
step_scale
,
22
-
shift
));
}
else
{
for
(
n
=
0
;
n
<
DCA_SUBBAND_SAMPLES
;
n
++
)
output
[
n
]
=
clip23
(
norm__
(
input
[
n
]
*
step_scale
,
22
-
shift
));
}
}
static
inline
void
inverse_adpcm
(
int32_t
**
subband_samples
,
static
inline
void
inverse_adpcm
(
int32_t
**
subband_samples
,
const
int16_t
*
vq_index
,
const
int16_t
*
vq_index
,
const
int8_t
*
prediction_mode
,
const
int8_t
*
prediction_mode
,
int
sb_start
,
int
sb_end
,
int
sb_start
,
int
sb_end
,
int
ofs
,
int
len
)
int
ofs
,
int
len
)
{
{
int
i
,
j
,
k
;
int
i
,
j
;
for
(
i
=
sb_start
;
i
<
sb_end
;
i
++
)
{
for
(
i
=
sb_start
;
i
<
sb_end
;
i
++
)
{
if
(
prediction_mode
[
i
])
{
if
(
prediction_mode
[
i
])
{
const
int
16_t
*
coeff
=
ff_dca_adpcm_vb
[
vq_index
[
i
]
];
const
int
pred_id
=
vq_index
[
i
];
int32_t
*
ptr
=
subband_samples
[
i
]
+
ofs
;
int32_t
*
ptr
=
subband_samples
[
i
]
+
ofs
;
for
(
j
=
0
;
j
<
len
;
j
++
)
{
for
(
j
=
0
;
j
<
len
;
j
++
)
{
int64_t
err
=
0
;
int32_t
x
=
ff_dcaadpcm_predict
(
pred_id
,
ptr
+
j
-
DCA_ADPCM_COEFFS
);
for
(
k
=
0
;
k
<
DCA_ADPCM_COEFFS
;
k
++
)
ptr
[
j
]
=
clip23
(
ptr
[
j
]
+
x
);
err
+=
(
int64_t
)
ptr
[
j
-
k
-
1
]
*
coeff
[
k
];
ptr
[
j
]
=
clip23
(
ptr
[
j
]
+
clip23
(
norm13
(
err
)));
}
}
}
}
}
}
...
@@ -817,8 +793,8 @@ static int parse_subframe_audio(DCACoreDecoder *s, int sf, enum HeaderType heade
...
@@ -817,8 +793,8 @@ static int parse_subframe_audio(DCACoreDecoder *s, int sf, enum HeaderType heade
scale
=
clip23
(
adj
*
scale
>>
22
);
scale
=
clip23
(
adj
*
scale
>>
22
);
}
}
dequantize
(
s
->
subband_samples
[
ch
][
band
]
+
ofs
,
ff_dca_core_
dequantize
(
s
->
subband_samples
[
ch
][
band
]
+
ofs
,
audio
,
step_size
,
scale
,
0
);
audio
,
step_size
,
scale
,
0
,
DCA_SUBBAND_SAMPLES
);
}
}
}
}
...
@@ -1146,8 +1122,8 @@ static int parse_xbr_subframe(DCACoreDecoder *s, int xbr_base_ch, int xbr_nchann
...
@@ -1146,8 +1122,8 @@ static int parse_xbr_subframe(DCACoreDecoder *s, int xbr_base_ch, int xbr_nchann
else
else
scale
=
xbr_scale_factors
[
ch
][
band
][
1
];
scale
=
xbr_scale_factors
[
ch
][
band
][
1
];
dequantize
(
s
->
subband_samples
[
ch
][
band
]
+
ofs
,
ff_dca_core_
dequantize
(
s
->
subband_samples
[
ch
][
band
]
+
ofs
,
audio
,
step_size
,
scale
,
1
);
audio
,
step_size
,
scale
,
1
,
DCA_SUBBAND_SAMPLES
);
}
}
}
}
...
@@ -1326,8 +1302,8 @@ static int parse_x96_subframe_audio(DCACoreDecoder *s, int sf, int xch_base, int
...
@@ -1326,8 +1302,8 @@ static int parse_x96_subframe_audio(DCACoreDecoder *s, int sf, int xch_base, int
// Get the scale factor
// Get the scale factor
scale
=
s
->
scale_factors
[
ch
][
band
>>
1
][
band
&
1
];
scale
=
s
->
scale_factors
[
ch
][
band
>>
1
][
band
&
1
];
dequantize
(
s
->
x96_subband_samples
[
ch
][
band
]
+
ofs
,
ff_dca_core_
dequantize
(
s
->
x96_subband_samples
[
ch
][
band
]
+
ofs
,
audio
,
step_size
,
scale
,
0
);
audio
,
step_size
,
scale
,
0
,
DCA_SUBBAND_SAMPLES
);
}
}
}
}
...
...
libavcodec/dca_core.h
View file @
b8c2b9c3
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include "dca_exss.h"
#include "dca_exss.h"
#include "dcadsp.h"
#include "dcadsp.h"
#include "dcadct.h"
#include "dcadct.h"
#include "dcamath.h"
#include "dcahuff.h"
#include "dcahuff.h"
#include "fft.h"
#include "fft.h"
#include "synth_filter.h"
#include "synth_filter.h"
...
@@ -43,7 +44,6 @@
...
@@ -43,7 +44,6 @@
#define DCA_SUBFRAMES 16
#define DCA_SUBFRAMES 16
#define DCA_SUBBAND_SAMPLES 8
#define DCA_SUBBAND_SAMPLES 8
#define DCA_PCMBLOCK_SAMPLES 32
#define DCA_PCMBLOCK_SAMPLES 32
#define DCA_ADPCM_COEFFS 4
#define DCA_LFE_HISTORY 8
#define DCA_LFE_HISTORY 8
#define DCA_ABITS_MAX 26
#define DCA_ABITS_MAX 26
...
@@ -195,6 +195,29 @@ static inline int ff_dca_core_map_spkr(DCACoreDecoder *core, int spkr)
...
@@ -195,6 +195,29 @@ static inline int ff_dca_core_map_spkr(DCACoreDecoder *core, int spkr)
return
-
1
;
return
-
1
;
}
}
static
inline
void
ff_dca_core_dequantize
(
int32_t
*
output
,
const
int32_t
*
input
,
int32_t
step_size
,
int32_t
scale
,
int
residual
,
int
len
)
{
// Account for quantizer step size
int64_t
step_scale
=
(
int64_t
)
step_size
*
scale
;
int
n
,
shift
=
0
;
// Limit scale factor resolution to 22 bits
if
(
step_scale
>
(
1
<<
23
))
{
shift
=
av_log2
(
step_scale
>>
23
)
+
1
;
step_scale
>>=
shift
;
}
// Scale the samples
if
(
residual
)
{
for
(
n
=
0
;
n
<
len
;
n
++
)
output
[
n
]
+=
clip23
(
norm__
(
input
[
n
]
*
step_scale
,
22
-
shift
));
}
else
{
for
(
n
=
0
;
n
<
len
;
n
++
)
output
[
n
]
=
clip23
(
norm__
(
input
[
n
]
*
step_scale
,
22
-
shift
));
}
}
int
ff_dca_core_parse
(
DCACoreDecoder
*
s
,
uint8_t
*
data
,
int
size
);
int
ff_dca_core_parse
(
DCACoreDecoder
*
s
,
uint8_t
*
data
,
int
size
);
int
ff_dca_core_parse_exss
(
DCACoreDecoder
*
s
,
uint8_t
*
data
,
DCAExssAsset
*
asset
);
int
ff_dca_core_parse_exss
(
DCACoreDecoder
*
s
,
uint8_t
*
data
,
DCAExssAsset
*
asset
);
int
ff_dca_core_filter_fixed
(
DCACoreDecoder
*
s
,
int
x96_synth
);
int
ff_dca_core_filter_fixed
(
DCACoreDecoder
*
s
,
int
x96_synth
);
...
...
libavcodec/dcaadpcm.c
0 → 100644
View file @
b8c2b9c3
/*
* DCA ADPCM engine
* Copyright (C) 2017 Daniil Cherednik
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dcaadpcm.h"
#include "dcaenc.h"
#include "dca_core.h"
#include "mathops.h"
typedef
int32_t
premultiplied_coeffs
[
10
];
//assume we have DCA_ADPCM_COEFFS values before x
static
inline
int64_t
calc_corr
(
const
int32_t
*
x
,
int
len
,
int
j
,
int
k
)
{
int
n
;
int64_t
s
=
0
;
for
(
n
=
0
;
n
<
len
;
n
++
)
s
+=
MUL64
(
x
[
n
-
j
],
x
[
n
-
k
]);
return
s
;
}
static
inline
int64_t
apply_filter
(
const
int16_t
a
[
DCA_ADPCM_COEFFS
],
const
int64_t
corr
[
15
],
const
int32_t
aa
[
10
])
{
int64_t
err
=
0
;
int64_t
tmp
=
0
;
err
=
corr
[
0
];
tmp
+=
MUL64
(
a
[
0
],
corr
[
1
]);
tmp
+=
MUL64
(
a
[
1
],
corr
[
2
]);
tmp
+=
MUL64
(
a
[
2
],
corr
[
3
]);
tmp
+=
MUL64
(
a
[
3
],
corr
[
4
]);
tmp
=
norm__
(
tmp
,
13
);
tmp
+=
tmp
;
err
-=
tmp
;
tmp
=
0
;
tmp
+=
MUL64
(
corr
[
5
],
aa
[
0
]);
tmp
+=
MUL64
(
corr
[
6
],
aa
[
1
]);
tmp
+=
MUL64
(
corr
[
7
],
aa
[
2
]);
tmp
+=
MUL64
(
corr
[
8
],
aa
[
3
]);
tmp
+=
MUL64
(
corr
[
9
],
aa
[
4
]);
tmp
+=
MUL64
(
corr
[
10
],
aa
[
5
]);
tmp
+=
MUL64
(
corr
[
11
],
aa
[
6
]);
tmp
+=
MUL64
(
corr
[
12
],
aa
[
7
]);
tmp
+=
MUL64
(
corr
[
13
],
aa
[
8
]);
tmp
+=
MUL64
(
corr
[
14
],
aa
[
9
]);
tmp
=
norm__
(
tmp
,
26
);
err
+=
tmp
;
return
llabs
(
err
);
}
static
int64_t
find_best_filter
(
const
DCAADPCMEncContext
*
s
,
const
int32_t
*
in
,
int
len
)
{
const
premultiplied_coeffs
*
precalc_data
=
s
->
private_data
;
int
i
,
j
,
k
=
0
;
int
vq
;
int64_t
err
;
int64_t
min_err
=
1ll
<<
62
;
int64_t
corr
[
15
];
for
(
i
=
0
;
i
<=
DCA_ADPCM_COEFFS
;
i
++
)
for
(
j
=
i
;
j
<=
DCA_ADPCM_COEFFS
;
j
++
)
corr
[
k
++
]
=
calc_corr
(
in
+
4
,
len
,
i
,
j
);
for
(
i
=
0
;
i
<
DCA_ADPCM_VQCODEBOOK_SZ
;
i
++
)
{
err
=
apply_filter
(
ff_dca_adpcm_vb
[
i
],
corr
,
*
precalc_data
);
if
(
err
<
min_err
)
{
min_err
=
err
;
vq
=
i
;
}
precalc_data
++
;
}
return
vq
;
}
static
inline
int64_t
calc_prediction_gain
(
int
pred_vq
,
const
int32_t
*
in
,
int32_t
*
out
,
int
len
)
{
int
i
;
int32_t
error
;
int64_t
signal_energy
=
0
;
int64_t
error_energy
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
error
=
in
[
DCA_ADPCM_COEFFS
+
i
]
-
ff_dcaadpcm_predict
(
pred_vq
,
in
+
i
);
out
[
i
]
=
error
;
signal_energy
+=
MUL64
(
in
[
DCA_ADPCM_COEFFS
+
i
],
in
[
DCA_ADPCM_COEFFS
+
i
]);
error_energy
+=
MUL64
(
error
,
error
);
}
if
(
!
error_energy
)
return
-
1
;
return
signal_energy
/
error_energy
;
}
int
ff_dcaadpcm_subband_analysis
(
const
DCAADPCMEncContext
*
s
,
const
int32_t
*
in
,
int
len
,
int
*
diff
)
{
int
pred_vq
,
i
;
int32_t
input_buffer
[
16
+
DCA_ADPCM_COEFFS
];
int32_t
input_buffer2
[
16
+
DCA_ADPCM_COEFFS
];
int32_t
max
=
0
;
int
shift_bits
;
uint64_t
pg
=
0
;
for
(
i
=
0
;
i
<
len
+
DCA_ADPCM_COEFFS
;
i
++
)
max
|=
FFABS
(
in
[
i
]);
// normalize input to simplify apply_filter
shift_bits
=
av_log2
(
max
)
-
11
;
for
(
i
=
0
;
i
<
len
+
DCA_ADPCM_COEFFS
;
i
++
)
{
input_buffer
[
i
]
=
norm__
(
in
[
i
],
7
);
input_buffer2
[
i
]
=
norm__
(
in
[
i
],
shift_bits
);
}
pred_vq
=
find_best_filter
(
s
,
input_buffer2
,
len
);
if
(
pred_vq
<
0
)
return
-
1
;
pg
=
calc_prediction_gain
(
pred_vq
,
input_buffer
,
diff
,
len
);
// Greater than 10db (10*log(10)) prediction gain to use ADPCM.
// TODO: Tune it.
if
(
pg
<
10
)
return
-
1
;
for
(
i
=
0
;
i
<
len
;
i
++
)
diff
[
i
]
<<=
7
;
return
pred_vq
;
}
static
void
precalc
(
premultiplied_coeffs
*
data
)
{
int
i
,
j
,
k
;
for
(
i
=
0
;
i
<
DCA_ADPCM_VQCODEBOOK_SZ
;
i
++
)
{
int
id
=
0
;
int32_t
t
=
0
;
for
(
j
=
0
;
j
<
DCA_ADPCM_COEFFS
;
j
++
)
{
for
(
k
=
j
;
k
<
DCA_ADPCM_COEFFS
;
k
++
)
{
t
=
(
int32_t
)
ff_dca_adpcm_vb
[
i
][
j
]
*
(
int32_t
)
ff_dca_adpcm_vb
[
i
][
k
];
if
(
j
!=
k
)
t
*=
2
;
(
*
data
)[
id
++
]
=
t
;
}
}
data
++
;
}
}
int
ff_dcaadpcm_do_real
(
int
pred_vq_index
,
softfloat
quant
,
int32_t
scale_factor
,
int32_t
step_size
,
const
int32_t
*
prev_hist
,
const
int32_t
*
in
,
int32_t
*
next_hist
,
int32_t
*
out
,
int
len
,
int32_t
peak
)
{
int
i
;
int64_t
delta
;
int32_t
dequant_delta
;
int32_t
work_bufer
[
16
+
DCA_ADPCM_COEFFS
];
memcpy
(
work_bufer
,
prev_hist
,
sizeof
(
int32_t
)
*
DCA_ADPCM_COEFFS
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
work_bufer
[
DCA_ADPCM_COEFFS
+
i
]
=
ff_dcaadpcm_predict
(
pred_vq_index
,
&
work_bufer
[
i
]);
delta
=
(
int64_t
)
in
[
i
]
-
((
int64_t
)
work_bufer
[
DCA_ADPCM_COEFFS
+
i
]
<<
7
);
out
[
i
]
=
quantize_value
(
av_clip64
(
delta
,
-
peak
,
peak
),
quant
);
ff_dca_core_dequantize
(
&
dequant_delta
,
&
out
[
i
],
step_size
,
scale_factor
,
0
,
1
);
work_bufer
[
DCA_ADPCM_COEFFS
+
i
]
+=
dequant_delta
;
}
memcpy
(
next_hist
,
&
work_bufer
[
len
],
sizeof
(
int32_t
)
*
DCA_ADPCM_COEFFS
);
return
0
;
}
av_cold
int
ff_dcaadpcm_init
(
DCAADPCMEncContext
*
s
)
{
if
(
!
s
)
return
-
1
;
s
->
private_data
=
av_malloc
(
sizeof
(
premultiplied_coeffs
)
*
DCA_ADPCM_VQCODEBOOK_SZ
);
precalc
(
s
->
private_data
);
return
0
;
}
av_cold
void
ff_dcaadpcm_free
(
DCAADPCMEncContext
*
s
)
{
if
(
!
s
)
return
;
av_freep
(
&
s
->
private_data
);
}
libavcodec/dcaadpcm.h
0 → 100644
View file @
b8c2b9c3
/*
* DCA ADPCM engine
* Copyright (C) 2017 Daniil Cherednik
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DCAADPCM_H
#define AVCODEC_DCAADPCM_H
#include "dcamath.h"
#include "dcadata.h"
#include "dcaenc.h"
typedef
struct
DCAADPCMEncContext
{
void
*
private_data
;
}
DCAADPCMEncContext
;
static
inline
int64_t
ff_dcaadpcm_predict
(
int
pred_vq_index
,
const
int32_t
*
input
)
{
int
i
;
const
int16_t
*
coeff
=
ff_dca_adpcm_vb
[
pred_vq_index
];
int64_t
pred
=
0
;
for
(
i
=
0
;
i
<
DCA_ADPCM_COEFFS
;
i
++
)
pred
+=
(
int64_t
)
input
[
DCA_ADPCM_COEFFS
-
1
-
i
]
*
coeff
[
i
];
return
clip23
(
norm13
(
pred
));
}
int
ff_dcaadpcm_subband_analysis
(
const
DCAADPCMEncContext
*
s
,
const
int32_t
*
input
,
int
len
,
int
*
diff
);
int
ff_dcaadpcm_do_real
(
int
pred_vq_index
,
softfloat
quant
,
int32_t
scale_factor
,
int32_t
step_size
,
const
int32_t
*
prev_hist
,
const
int32_t
*
in
,
int32_t
*
next_hist
,
int32_t
*
out
,
int
len
,
int32_t
peak
);
av_cold
int
ff_dcaadpcm_init
(
DCAADPCMEncContext
*
s
);
av_cold
void
ff_dcaadpcm_free
(
DCAADPCMEncContext
*
s
);
#endif
/* AVCODEC_DCAADPCM_H */
libavcodec/dcadata.c
View file @
b8c2b9c3
...
@@ -61,7 +61,7 @@ const uint8_t ff_dca_quant_index_group_size[DCA_CODE_BOOKS] = {
...
@@ -61,7 +61,7 @@ const uint8_t ff_dca_quant_index_group_size[DCA_CODE_BOOKS] = {
/* ADPCM data */
/* ADPCM data */
/* 16 bits signed fractional Q13 binary codes */
/* 16 bits signed fractional Q13 binary codes */
const
int16_t
ff_dca_adpcm_vb
[
4096
][
4
]
=
{
const
int16_t
ff_dca_adpcm_vb
[
DCA_ADPCM_VQCODEBOOK_SZ
][
DCA_ADPCM_COEFFS
]
=
{
{
9928
,
-
2618
,
-
1093
,
-
1263
},
{
9928
,
-
2618
,
-
1093
,
-
1263
},
{
11077
,
-
2876
,
-
1747
,
-
308
},
{
11077
,
-
2876
,
-
1747
,
-
308
},
{
10503
,
-
1082
,
-
1426
,
-
1167
},
{
10503
,
-
1082
,
-
1426
,
-
1167
},
...
...
libavcodec/dcadata.h
View file @
b8c2b9c3
...
@@ -25,6 +25,9 @@
...
@@ -25,6 +25,9 @@
#include "dcahuff.h"
#include "dcahuff.h"
#define DCA_ADPCM_COEFFS 4
#define DCA_ADPCM_VQCODEBOOK_SZ 4096
extern
const
uint32_t
ff_dca_bit_rates
[
32
];
extern
const
uint32_t
ff_dca_bit_rates
[
32
];
extern
const
uint8_t
ff_dca_channels
[
16
];
extern
const
uint8_t
ff_dca_channels
[
16
];
...
@@ -36,7 +39,7 @@ extern const uint8_t ff_dca_dmix_primary_nch[8];
...
@@ -36,7 +39,7 @@ extern const uint8_t ff_dca_dmix_primary_nch[8];
extern
const
uint8_t
ff_dca_quant_index_sel_nbits
[
DCA_CODE_BOOKS
];
extern
const
uint8_t
ff_dca_quant_index_sel_nbits
[
DCA_CODE_BOOKS
];
extern
const
uint8_t
ff_dca_quant_index_group_size
[
DCA_CODE_BOOKS
];
extern
const
uint8_t
ff_dca_quant_index_group_size
[
DCA_CODE_BOOKS
];
extern
const
int16_t
ff_dca_adpcm_vb
[
4096
][
4
];
extern
const
int16_t
ff_dca_adpcm_vb
[
DCA_ADPCM_VQCODEBOOK_SZ
][
DCA_ADPCM_COEFFS
];
extern
const
uint32_t
ff_dca_scale_factor_quant6
[
64
];
extern
const
uint32_t
ff_dca_scale_factor_quant6
[
64
];
extern
const
uint32_t
ff_dca_scale_factor_quant7
[
128
];
extern
const
uint32_t
ff_dca_scale_factor_quant7
[
128
];
...
...
libavcodec/dcaenc.c
View file @
b8c2b9c3
...
@@ -25,8 +25,12 @@
...
@@ -25,8 +25,12 @@
#include "libavutil/channel_layout.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/common.h"
#include "libavutil/ffmath.h"
#include "libavutil/ffmath.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "avcodec.h"
#include "dca.h"
#include "dca.h"
#include "dcaadpcm.h"
#include "dcamath.h"
#include "dca_core.h"
#include "dcadata.h"
#include "dcadata.h"
#include "dcaenc.h"
#include "dcaenc.h"
#include "internal.h"
#include "internal.h"
...
@@ -44,8 +48,15 @@
...
@@ -44,8 +48,15 @@
#define SUBBAND_SAMPLES (SUBFRAMES * SUBSUBFRAMES * 8)
#define SUBBAND_SAMPLES (SUBFRAMES * SUBSUBFRAMES * 8)
#define AUBANDS 25
#define AUBANDS 25
typedef
struct
CompressionOptions
{
int
adpcm_mode
;
}
CompressionOptions
;
typedef
struct
DCAEncContext
{
typedef
struct
DCAEncContext
{
AVClass
*
class
;
PutBitContext
pb
;
PutBitContext
pb
;
DCAADPCMEncContext
adpcm_ctx
;
CompressionOptions
options
;
int
frame_size
;
int
frame_size
;
int
frame_bits
;
int
frame_bits
;
int
fullband_channels
;
int
fullband_channels
;
...
@@ -61,10 +72,13 @@ typedef struct DCAEncContext {
...
@@ -61,10 +72,13 @@ typedef struct DCAEncContext {
int32_t
lfe_peak_cb
;
int32_t
lfe_peak_cb
;
const
int8_t
*
channel_order_tab
;
///< channel reordering table, lfe and non lfe
const
int8_t
*
channel_order_tab
;
///< channel reordering table, lfe and non lfe
int32_t
prediction_mode
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
];
int32_t
adpcm_history
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
][
DCA_ADPCM_COEFFS
*
2
];
int32_t
history
[
MAX_CHANNELS
][
512
];
/* This is a circular buffer */
int32_t
history
[
MAX_CHANNELS
][
512
];
/* This is a circular buffer */
int32_t
subband
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
][
SUBBAND_SAMPLE
S
];
int32_t
*
subband
[
MAX_CHANNELS
][
DCAENC_SUBBAND
S
];
int32_t
quantized
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
][
SUBBAND_SAMPLES
];
int32_t
quantized
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
][
SUBBAND_SAMPLES
];
int32_t
peak_cb
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
];
int32_t
peak_cb
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
];
int32_t
diff_peak_cb
[
MAX_CHANNELS
][
DCAENC_SUBBANDS
];
///< expected peak of residual signal
int32_t
downsampled_lfe
[
DCA_LFE_SAMPLES
];
int32_t
downsampled_lfe
[
DCA_LFE_SAMPLES
];
int32_t
masking_curve_cb
[
SUBSUBFRAMES
][
256
];
int32_t
masking_curve_cb
[
SUBSUBFRAMES
][
256
];
int32_t
bit_allocation_sel
[
MAX_CHANNELS
];
int32_t
bit_allocation_sel
[
MAX_CHANNELS
];
...
@@ -77,6 +91,7 @@ typedef struct DCAEncContext {
...
@@ -77,6 +91,7 @@ typedef struct DCAEncContext {
int32_t
worst_quantization_noise
;
int32_t
worst_quantization_noise
;
int32_t
worst_noise_ever
;
int32_t
worst_noise_ever
;
int
consumed_bits
;
int
consumed_bits
;
int
consumed_adpcm_bits
;
///< Number of bits to transmit ADPCM related info
}
DCAEncContext
;
}
DCAEncContext
;
static
int32_t
cos_table
[
2048
];
static
int32_t
cos_table
[
2048
];
...
@@ -107,18 +122,52 @@ static double gammafilter(int i, double f)
...
@@ -107,18 +122,52 @@ static double gammafilter(int i, double f)
return
20
*
log10
(
h
);
return
20
*
log10
(
h
);
}
}
static
int
subband_bufer_alloc
(
DCAEncContext
*
c
)
{
int
ch
,
band
;
int32_t
*
bufer
=
av_calloc
(
MAX_CHANNELS
*
DCAENC_SUBBANDS
*
(
SUBBAND_SAMPLES
+
DCA_ADPCM_COEFFS
),
sizeof
(
int32_t
));
if
(
!
bufer
)
return
-
1
;
/* we need a place for DCA_ADPCM_COEFF samples from previous frame
* to calc prediction coefficients for each subband */
for
(
ch
=
0
;
ch
<
MAX_CHANNELS
;
ch
++
)
{
for
(
band
=
0
;
band
<
DCAENC_SUBBANDS
;
band
++
)
{
c
->
subband
[
ch
][
band
]
=
bufer
+
ch
*
DCAENC_SUBBANDS
*
(
SUBBAND_SAMPLES
+
DCA_ADPCM_COEFFS
)
+
band
*
(
SUBBAND_SAMPLES
+
DCA_ADPCM_COEFFS
)
+
DCA_ADPCM_COEFFS
;
}
}
return
0
;
}
static
void
subband_bufer_free
(
DCAEncContext
*
c
)
{
int32_t
*
bufer
=
c
->
subband
[
0
][
0
]
-
DCA_ADPCM_COEFFS
;
av_freep
(
&
bufer
);
}
static
int
encode_init
(
AVCodecContext
*
avctx
)
static
int
encode_init
(
AVCodecContext
*
avctx
)
{
{
DCAEncContext
*
c
=
avctx
->
priv_data
;
DCAEncContext
*
c
=
avctx
->
priv_data
;
uint64_t
layout
=
avctx
->
channel_layout
;
uint64_t
layout
=
avctx
->
channel_layout
;
int
i
,
j
,
min_frame_bits
;
int
i
,
j
,
min_frame_bits
;
if
(
subband_bufer_alloc
(
c
))
return
AVERROR
(
ENOMEM
);
c
->
fullband_channels
=
c
->
channels
=
avctx
->
channels
;
c
->
fullband_channels
=
c
->
channels
=
avctx
->
channels
;
c
->
lfe_channel
=
(
avctx
->
channels
==
3
||
avctx
->
channels
==
6
);
c
->
lfe_channel
=
(
avctx
->
channels
==
3
||
avctx
->
channels
==
6
);
c
->
band_interpolation
=
band_interpolation
[
1
];
c
->
band_interpolation
=
band_interpolation
[
1
];
c
->
band_spectrum
=
band_spectrum
[
1
];
c
->
band_spectrum
=
band_spectrum
[
1
];
c
->
worst_quantization_noise
=
-
2047
;
c
->
worst_quantization_noise
=
-
2047
;
c
->
worst_noise_ever
=
-
2047
;
c
->
worst_noise_ever
=
-
2047
;
c
->
consumed_adpcm_bits
=
0
;
if
(
ff_dcaadpcm_init
(
&
c
->
adpcm_ctx
))
return
AVERROR
(
ENOMEM
);
if
(
!
layout
)
{
if
(
!
layout
)
{
av_log
(
avctx
,
AV_LOG_WARNING
,
"No channel layout specified. The "
av_log
(
avctx
,
AV_LOG_WARNING
,
"No channel layout specified. The "
...
@@ -150,6 +199,12 @@ static int encode_init(AVCodecContext *avctx)
...
@@ -150,6 +199,12 @@ static int encode_init(AVCodecContext *avctx)
}
}
/* 6 - no Huffman */
/* 6 - no Huffman */
c
->
bit_allocation_sel
[
i
]
=
6
;
c
->
bit_allocation_sel
[
i
]
=
6
;
for
(
j
=
0
;
j
<
DCAENC_SUBBANDS
;
j
++
)
{
/* -1 - no ADPCM */
c
->
prediction_mode
[
i
][
j
]
=
-
1
;
memset
(
c
->
adpcm_history
[
i
][
j
],
0
,
sizeof
(
int32_t
)
*
DCA_ADPCM_COEFFS
);
}
}
}
for
(
i
=
0
;
i
<
9
;
i
++
)
{
for
(
i
=
0
;
i
<
9
;
i
++
)
{
...
@@ -238,6 +293,16 @@ static int encode_init(AVCodecContext *avctx)
...
@@ -238,6 +293,16 @@ static int encode_init(AVCodecContext *avctx)
return
0
;
return
0
;
}
}
static
av_cold
int
encode_close
(
AVCodecContext
*
avctx
)
{
if
(
avctx
->
priv_data
)
{
DCAEncContext
*
c
=
avctx
->
priv_data
;
subband_bufer_free
(
c
);
ff_dcaadpcm_free
(
&
c
->
adpcm_ctx
);
}
return
0
;
}
static
inline
int32_t
cos_t
(
int
x
)
static
inline
int32_t
cos_t
(
int
x
)
{
{
return
cos_table
[
x
&
2047
];
return
cos_table
[
x
&
2047
];
...
@@ -253,12 +318,6 @@ static inline int32_t half32(int32_t a)
...
@@ -253,12 +318,6 @@ static inline int32_t half32(int32_t a)
return
(
a
+
1
)
>>
1
;
return
(
a
+
1
)
>>
1
;
}
}
static
inline
int32_t
mul32
(
int32_t
a
,
int32_t
b
)
{
int64_t
r
=
(
int64_t
)
a
*
b
+
0x80000000ULL
;
return
r
>>
32
;
}
static
void
subband_transform
(
DCAEncContext
*
c
,
const
int32_t
*
input
)
static
void
subband_transform
(
DCAEncContext
*
c
,
const
int32_t
*
input
)
{
{
int
ch
,
subs
,
i
,
k
,
j
;
int
ch
,
subs
,
i
,
k
,
j
;
...
@@ -545,31 +604,53 @@ static void calc_masking(DCAEncContext *c, const int32_t *input)
...
@@ -545,31 +604,53 @@ static void calc_masking(DCAEncContext *c, const int32_t *input)
}
}
}
}
static
inline
int32_t
find_peak
(
const
int32_t
*
in
,
int
len
)
{
int
sample
;
int32_t
m
=
0
;
for
(
sample
=
0
;
sample
<
len
;
sample
++
)
{
int32_t
s
=
abs
(
in
[
sample
]);
if
(
m
<
s
)
{
m
=
s
;
}
}
return
get_cb
(
m
);
}
static
void
find_peaks
(
DCAEncContext
*
c
)
static
void
find_peaks
(
DCAEncContext
*
c
)
{
{
int
band
,
ch
;
int
band
,
ch
;
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
{
for
(
band
=
0
;
band
<
32
;
band
++
)
{
for
(
band
=
0
;
band
<
32
;
band
++
)
{
int
sample
;
c
->
peak_cb
[
ch
][
band
]
=
find_peak
(
c
->
subband
[
ch
][
band
],
SUBBAND_SAMPLES
);
int32_t
m
=
0
;
for
(
sample
=
0
;
sample
<
SUBBAND_SAMPLES
;
sample
++
)
{
int32_t
s
=
abs
(
c
->
subband
[
ch
][
band
][
sample
]);
if
(
m
<
s
)
m
=
s
;
}
c
->
peak_cb
[
ch
][
band
]
=
get_cb
(
m
);
}
}
}
if
(
c
->
lfe_channel
)
{
if
(
c
->
lfe_channel
)
{
int
sample
;
c
->
lfe_peak_cb
=
find_peak
(
c
->
downsampled_lfe
,
DCA_LFE_SAMPLES
);
int32_t
m
=
0
;
}
}
static
void
adpcm_analysis
(
DCAEncContext
*
c
)
{
int
ch
,
band
;
int
pred_vq_id
;
int32_t
*
samples
;
int32_t
estimated_diff
[
SUBBAND_SAMPLES
];
for
(
sample
=
0
;
sample
<
DCA_LFE_SAMPLES
;
sample
++
)
c
->
consumed_adpcm_bits
=
0
;
if
(
m
<
abs
(
c
->
downsampled_lfe
[
sample
]))
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
{
m
=
abs
(
c
->
downsampled_lfe
[
sample
]);
for
(
band
=
0
;
band
<
32
;
band
++
)
{
c
->
lfe_peak_cb
=
get_cb
(
m
);
samples
=
c
->
subband
[
ch
][
band
]
-
DCA_ADPCM_COEFFS
;
pred_vq_id
=
ff_dcaadpcm_subband_analysis
(
&
c
->
adpcm_ctx
,
samples
,
SUBBAND_SAMPLES
,
estimated_diff
);
if
(
pred_vq_id
>=
0
)
{
c
->
prediction_mode
[
ch
][
band
]
=
pred_vq_id
;
c
->
consumed_adpcm_bits
+=
12
;
//12 bits to transmit prediction vq index
c
->
diff_peak_cb
[
ch
][
band
]
=
find_peak
(
estimated_diff
,
16
);
}
else
{
c
->
prediction_mode
[
ch
][
band
]
=
-
1
;
}
}
}
}
}
}
...
@@ -578,13 +659,16 @@ static const int snr_fudge = 128;
...
@@ -578,13 +659,16 @@ static const int snr_fudge = 128;
#define USED_NABITS 2
#define USED_NABITS 2
#define USED_26ABITS 4
#define USED_26ABITS 4
static
in
t32_t
quantize_value
(
int32_t
value
,
softfloat
quant
)
static
in
line
int32_t
get_step_size
(
const
DCAEncContext
*
c
,
int
ch
,
int
band
)
{
{
int32_t
offset
=
1
<<
(
quant
.
e
-
1
)
;
int32_t
step_size
;
value
=
mul32
(
value
,
quant
.
m
)
+
offset
;
if
(
c
->
bitrate_index
==
3
)
value
=
value
>>
quant
.
e
;
step_size
=
ff_dca_lossless_quant
[
c
->
abits
[
ch
][
band
]];
return
value
;
else
step_size
=
ff_dca_lossy_quant
[
c
->
abits
[
ch
][
band
]];
return
step_size
;
}
}
static
int
calc_one_scale
(
int32_t
peak_cb
,
int
abits
,
softfloat
*
quant
)
static
int
calc_one_scale
(
int32_t
peak_cb
,
int
abits
,
softfloat
*
quant
)
...
@@ -619,14 +703,40 @@ static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant)
...
@@ -619,14 +703,40 @@ static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant)
return
our_nscale
;
return
our_nscale
;
}
}
static
void
quantize_all
(
DCAEncContext
*
c
)
static
inline
void
quantize_adpcm_subband
(
DCAEncContext
*
c
,
int
ch
,
int
band
)
{
int32_t
step_size
;
int32_t
diff_peak_cb
=
c
->
diff_peak_cb
[
ch
][
band
];
c
->
scale_factor
[
ch
][
band
]
=
calc_one_scale
(
diff_peak_cb
,
c
->
abits
[
ch
][
band
],
&
c
->
quant
[
ch
][
band
]);
step_size
=
get_step_size
(
c
,
ch
,
band
);
ff_dcaadpcm_do_real
(
c
->
prediction_mode
[
ch
][
band
],
c
->
quant
[
ch
][
band
],
ff_dca_scale_factor_quant7
[
c
->
scale_factor
[
ch
][
band
]],
step_size
,
c
->
adpcm_history
[
ch
][
band
],
c
->
subband
[
ch
][
band
],
c
->
adpcm_history
[
ch
][
band
]
+
4
,
c
->
quantized
[
ch
][
band
],
SUBBAND_SAMPLES
,
cb_to_level
[
-
diff_peak_cb
]);
}
static
void
quantize_adpcm
(
DCAEncContext
*
c
)
{
int
band
,
ch
;
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
band
=
0
;
band
<
32
;
band
++
)
if
(
c
->
prediction_mode
[
ch
][
band
]
>=
0
)
quantize_adpcm_subband
(
c
,
ch
,
band
);
}
static
void
quantize_pcm
(
DCAEncContext
*
c
)
{
{
int
sample
,
band
,
ch
;
int
sample
,
band
,
ch
;
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
band
=
0
;
band
<
32
;
band
++
)
for
(
band
=
0
;
band
<
32
;
band
++
)
for
(
sample
=
0
;
sample
<
SUBBAND_SAMPLES
;
sample
++
)
if
(
c
->
prediction_mode
[
ch
][
band
]
==
-
1
)
c
->
quantized
[
ch
][
band
][
sample
]
=
quantize_value
(
c
->
subband
[
ch
][
band
][
sample
],
c
->
quant
[
ch
][
band
]);
for
(
sample
=
0
;
sample
<
SUBBAND_SAMPLES
;
sample
++
)
c
->
quantized
[
ch
][
band
][
sample
]
=
quantize_value
(
c
->
subband
[
ch
][
band
][
sample
],
c
->
quant
[
ch
][
band
]);
}
}
static
void
accumulate_huff_bit_consumption
(
int
abits
,
int32_t
*
quantized
,
uint32_t
*
result
)
static
void
accumulate_huff_bit_consumption
(
int
abits
,
int32_t
*
quantized
,
uint32_t
*
result
)
...
@@ -710,6 +820,7 @@ static int init_quantization_noise(DCAEncContext *c, int noise)
...
@@ -710,6 +820,7 @@ static int init_quantization_noise(DCAEncContext *c, int noise)
uint32_t
bits_counter
=
0
;
uint32_t
bits_counter
=
0
;
c
->
consumed_bits
=
132
+
333
*
c
->
fullband_channels
;
c
->
consumed_bits
=
132
+
333
*
c
->
fullband_channels
;
c
->
consumed_bits
+=
c
->
consumed_adpcm_bits
;
if
(
c
->
lfe_channel
)
if
(
c
->
lfe_channel
)
c
->
consumed_bits
+=
72
;
c
->
consumed_bits
+=
72
;
...
@@ -740,12 +851,15 @@ static int init_quantization_noise(DCAEncContext *c, int noise)
...
@@ -740,12 +851,15 @@ static int init_quantization_noise(DCAEncContext *c, int noise)
/* TODO: May be cache scaled values */
/* TODO: May be cache scaled values */
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
{
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
{
for
(
band
=
0
;
band
<
32
;
band
++
)
{
for
(
band
=
0
;
band
<
32
;
band
++
)
{
c
->
scale_factor
[
ch
][
band
]
=
calc_one_scale
(
c
->
peak_cb
[
ch
][
band
],
if
(
c
->
prediction_mode
[
ch
][
band
]
==
-
1
)
{
c
->
abits
[
ch
][
band
],
c
->
scale_factor
[
ch
][
band
]
=
calc_one_scale
(
c
->
peak_cb
[
ch
][
band
],
&
c
->
quant
[
ch
][
band
]);
c
->
abits
[
ch
][
band
],
&
c
->
quant
[
ch
][
band
]);
}
}
}
}
}
quantize_all
(
c
);
quantize_adpcm
(
c
);
quantize_pcm
(
c
);
memset
(
huff_bit_count_accum
,
0
,
MAX_CHANNELS
*
DCA_CODE_BOOKS
*
7
*
sizeof
(
uint32_t
));
memset
(
huff_bit_count_accum
,
0
,
MAX_CHANNELS
*
DCA_CODE_BOOKS
*
7
*
sizeof
(
uint32_t
));
memset
(
clc_bit_count_accum
,
0
,
MAX_CHANNELS
*
DCA_CODE_BOOKS
*
sizeof
(
uint32_t
));
memset
(
clc_bit_count_accum
,
0
,
MAX_CHANNELS
*
DCA_CODE_BOOKS
*
sizeof
(
uint32_t
));
...
@@ -819,6 +933,41 @@ static void shift_history(DCAEncContext *c, const int32_t *input)
...
@@ -819,6 +933,41 @@ static void shift_history(DCAEncContext *c, const int32_t *input)
}
}
}
}
static
void
fill_in_adpcm_bufer
(
DCAEncContext
*
c
)
{
int
ch
,
band
;
int32_t
step_size
;
/* We fill in ADPCM work buffer for subbands which hasn't been ADPCM coded
* in current frame - we need this data if subband of next frame is
* ADPCM
*/
for
(
ch
=
0
;
ch
<
c
->
channels
;
ch
++
)
{
for
(
band
=
0
;
band
<
32
;
band
++
)
{
int32_t
*
samples
=
c
->
subband
[
ch
][
band
]
-
DCA_ADPCM_COEFFS
;
if
(
c
->
prediction_mode
[
ch
][
band
]
==
-
1
)
{
step_size
=
get_step_size
(
c
,
ch
,
band
);
ff_dca_core_dequantize
(
c
->
adpcm_history
[
ch
][
band
],
c
->
quantized
[
ch
][
band
]
+
12
,
step_size
,
ff_dca_scale_factor_quant7
[
c
->
scale_factor
[
ch
][
band
]],
0
,
4
);
}
else
{
AV_COPY128U
(
c
->
adpcm_history
[
ch
][
band
],
c
->
adpcm_history
[
ch
][
band
]
+
4
);
}
/* Copy dequantized values for LPC analysis.
* It reduces artifacts in case of extreme quantization,
* example: in current frame abits is 1 and has no prediction flag,
* but end of this frame is sine like signal. In this case, if LPC analysis uses
* original values, likely LPC analysis returns good prediction gain, and sets prediction flag.
* But there are no proper value in decoder history, so likely result will be no good.
* Bitstream has "Predictor history flag switch", but this flag disables history for all subbands
*/
samples
[
0
]
=
c
->
adpcm_history
[
ch
][
band
][
0
]
<<
7
;
samples
[
1
]
=
c
->
adpcm_history
[
ch
][
band
][
1
]
<<
7
;
samples
[
2
]
=
c
->
adpcm_history
[
ch
][
band
][
2
]
<<
7
;
samples
[
3
]
=
c
->
adpcm_history
[
ch
][
band
][
3
]
<<
7
;
}
}
}
static
void
calc_lfe_scales
(
DCAEncContext
*
c
)
static
void
calc_lfe_scales
(
DCAEncContext
*
c
)
{
{
if
(
c
->
lfe_channel
)
if
(
c
->
lfe_channel
)
...
@@ -1001,9 +1150,14 @@ static void put_subframe(DCAEncContext *c, int subframe)
...
@@ -1001,9 +1150,14 @@ static void put_subframe(DCAEncContext *c, int subframe)
/* Prediction mode: no ADPCM, in each channel and subband */
/* Prediction mode: no ADPCM, in each channel and subband */
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
band
=
0
;
band
<
DCAENC_SUBBANDS
;
band
++
)
for
(
band
=
0
;
band
<
DCAENC_SUBBANDS
;
band
++
)
put_bits
(
&
c
->
pb
,
1
,
0
);
put_bits
(
&
c
->
pb
,
1
,
!
(
c
->
prediction_mode
[
ch
][
band
]
==
-
1
));
/* Prediction VQ address */
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
for
(
band
=
0
;
band
<
DCAENC_SUBBANDS
;
band
++
)
if
(
c
->
prediction_mode
[
ch
][
band
]
>=
0
)
put_bits
(
&
c
->
pb
,
12
,
c
->
prediction_mode
[
ch
][
band
]);
/* Prediction VQ address: not transmitted */
/* Bit allocation index */
/* Bit allocation index */
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
{
for
(
ch
=
0
;
ch
<
c
->
fullband_channels
;
ch
++
)
{
if
(
c
->
bit_allocation_sel
[
ch
]
==
6
)
{
if
(
c
->
bit_allocation_sel
[
ch
]
==
6
)
{
...
@@ -1068,12 +1222,15 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
...
@@ -1068,12 +1222,15 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
lfe_downsample
(
c
,
samples
);
lfe_downsample
(
c
,
samples
);
calc_masking
(
c
,
samples
);
calc_masking
(
c
,
samples
);
if
(
c
->
options
.
adpcm_mode
)
adpcm_analysis
(
c
);
find_peaks
(
c
);
find_peaks
(
c
);
assign_bits
(
c
);
assign_bits
(
c
);
calc_lfe_scales
(
c
);
calc_lfe_scales
(
c
);
shift_history
(
c
,
samples
);
shift_history
(
c
,
samples
);
init_put_bits
(
&
c
->
pb
,
avpkt
->
data
,
avpkt
->
size
);
init_put_bits
(
&
c
->
pb
,
avpkt
->
data
,
avpkt
->
size
);
fill_in_adpcm_bufer
(
c
);
put_frame_header
(
c
);
put_frame_header
(
c
);
put_primary_audio_header
(
c
);
put_primary_audio_header
(
c
);
for
(
i
=
0
;
i
<
SUBFRAMES
;
i
++
)
for
(
i
=
0
;
i
<
SUBFRAMES
;
i
++
)
...
@@ -1092,6 +1249,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
...
@@ -1092,6 +1249,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
return
0
;
return
0
;
}
}
#define DCAENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static
const
AVOption
options
[]
=
{
{
"dca_adpcm"
,
"Use ADPCM encoding"
,
offsetof
(
DCAEncContext
,
options
.
adpcm_mode
),
AV_OPT_TYPE_BOOL
,
{.
i64
=
0
},
0
,
1
,
DCAENC_FLAGS
},
{
NULL
},
};
static
const
AVClass
dcaenc_class
=
{
.
class_name
=
"DCA (DTS Coherent Acoustics)"
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
static
const
AVCodecDefault
defaults
[]
=
{
static
const
AVCodecDefault
defaults
[]
=
{
{
"b"
,
"1411200"
},
{
"b"
,
"1411200"
},
{
NULL
},
{
NULL
},
...
@@ -1104,6 +1275,7 @@ AVCodec ff_dca_encoder = {
...
@@ -1104,6 +1275,7 @@ AVCodec ff_dca_encoder = {
.
id
=
AV_CODEC_ID_DTS
,
.
id
=
AV_CODEC_ID_DTS
,
.
priv_data_size
=
sizeof
(
DCAEncContext
),
.
priv_data_size
=
sizeof
(
DCAEncContext
),
.
init
=
encode_init
,
.
init
=
encode_init
,
.
close
=
encode_close
,
.
encode2
=
encode_frame
,
.
encode2
=
encode_frame
,
.
capabilities
=
AV_CODEC_CAP_EXPERIMENTAL
,
.
capabilities
=
AV_CODEC_CAP_EXPERIMENTAL
,
.
sample_fmts
=
(
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S32
,
.
sample_fmts
=
(
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S32
,
...
@@ -1116,4 +1288,5 @@ AVCodec ff_dca_encoder = {
...
@@ -1116,4 +1288,5 @@ AVCodec ff_dca_encoder = {
AV_CH_LAYOUT_5POINT1
,
AV_CH_LAYOUT_5POINT1
,
0
},
0
},
.
defaults
=
defaults
,
.
defaults
=
defaults
,
.
priv_class
=
&
dcaenc_class
,
};
};
libavcodec/dcaenc.h
View file @
b8c2b9c3
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#include <stdint.h>
#include <stdint.h>
#include "dcamath.h"
typedef
struct
{
typedef
struct
{
int32_t
m
;
int32_t
m
;
int32_t
e
;
int32_t
e
;
...
@@ -144,4 +146,13 @@ static const int8_t channel_reorder_nolfe[16][9] = {
...
@@ -144,4 +146,13 @@ static const int8_t channel_reorder_nolfe[16][9] = {
{
3
,
2
,
4
,
0
,
1
,
5
,
7
,
6
,
-
1
},
{
3
,
2
,
4
,
0
,
1
,
5
,
7
,
6
,
-
1
},
};
};
static
inline
int32_t
quantize_value
(
int32_t
value
,
softfloat
quant
)
{
int32_t
offset
=
1
<<
(
quant
.
e
-
1
);
value
=
mul32
(
value
,
quant
.
m
)
+
offset
;
value
=
value
>>
quant
.
e
;
return
value
;
}
#endif
/* AVCODEC_DCAENC_H */
#endif
/* AVCODEC_DCAENC_H */
libavcodec/dcamath.h
View file @
b8c2b9c3
...
@@ -49,6 +49,7 @@ static inline int32_t mul17(int32_t a, int32_t b) { return mul__(a, b, 17); }
...
@@ -49,6 +49,7 @@ static inline int32_t mul17(int32_t a, int32_t b) { return mul__(a, b, 17); }
static
inline
int32_t
mul22
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
22
);
}
static
inline
int32_t
mul22
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
22
);
}
static
inline
int32_t
mul23
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
23
);
}
static
inline
int32_t
mul23
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
23
);
}
static
inline
int32_t
mul31
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
31
);
}
static
inline
int32_t
mul31
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
31
);
}
static
inline
int32_t
mul32
(
int32_t
a
,
int32_t
b
)
{
return
mul__
(
a
,
b
,
32
);
}
static
inline
int32_t
clip23
(
int32_t
a
)
{
return
av_clip_intp2
(
a
,
23
);
}
static
inline
int32_t
clip23
(
int32_t
a
)
{
return
av_clip_intp2
(
a
,
23
);
}
...
...
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