Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
ca048266
F
Ffmpeg
项目概览
小白菜888
/
Ffmpeg
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
Ffmpeg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ca048266
编写于
8月 17, 2008
作者:
R
Ramiro Polla
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Import more ok'd parts of ALAC encoder from GSoC repo.
Originally committed as revision 14820 to
svn://svn.ffmpeg.org/ffmpeg/trunk
上级
46dd2738
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
125 addition
and
15 deletion
+125
-15
libavcodec/alacenc.c
libavcodec/alacenc.c
+125
-15
未找到文件。
libavcodec/alacenc.c
浏览文件 @
ca048266
...
...
@@ -33,15 +33,52 @@
#define ALAC_ESCAPE_CODE 0x1FF
#define ALAC_MAX_LPC_ORDER 30
#define DEFAULT_MAX_PRED_ORDER 6
#define DEFAULT_MIN_PRED_ORDER 4
#define ALAC_MAX_LPC_PRECISION 9
#define ALAC_MAX_LPC_SHIFT 9
typedef
struct
RiceContext
{
int
history_mult
;
int
initial_history
;
int
k_modifier
;
int
rice_modifier
;
}
RiceContext
;
typedef
struct
LPCContext
{
int
lpc_order
;
int
lpc_coeff
[
ALAC_MAX_LPC_ORDER
+
1
];
int
lpc_quant
;
}
LPCContext
;
typedef
struct
AlacEncodeContext
{
int
compression_level
;
int
max_coded_frame_size
;
int
write_sample_size
;
int32_t
sample_buf
[
MAX_CHANNELS
][
DEFAULT_FRAME_SIZE
];
int
interlacing_shift
;
int
interlacing_leftweight
;
PutBitContext
pbctx
;
RiceContext
rc
;
LPCContext
lpc
[
MAX_CHANNELS
];
DSPContext
dspctx
;
AVCodecContext
*
avctx
;
}
AlacEncodeContext
;
static
void
init_sample_buffers
(
AlacEncodeContext
*
s
,
int16_t
*
input_samples
)
{
int
ch
,
i
;
for
(
ch
=
0
;
ch
<
s
->
avctx
->
channels
;
ch
++
)
{
int16_t
*
sptr
=
input_samples
+
ch
;
for
(
i
=
0
;
i
<
s
->
avctx
->
frame_size
;
i
++
)
{
s
->
sample_buf
[
ch
][
i
]
=
*
sptr
;
sptr
+=
s
->
avctx
->
channels
;
}
}
}
static
void
encode_scalar
(
AlacEncodeContext
*
s
,
int
x
,
int
k
,
int
write_sample_size
)
{
int
divisor
,
q
,
r
;
...
...
@@ -71,7 +108,7 @@ static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_s
static
void
write_frame_header
(
AlacEncodeContext
*
s
,
int
is_verbatim
)
{
put_bits
(
&
s
->
pbctx
,
3
,
s
->
channels
-
1
);
// No. of channels -1
put_bits
(
&
s
->
pbctx
,
3
,
s
->
avctx
->
channels
-
1
);
// No. of channels -1
put_bits
(
&
s
->
pbctx
,
16
,
0
);
// Seems to be zero
put_bits
(
&
s
->
pbctx
,
1
,
1
);
// Sample count is in the header
put_bits
(
&
s
->
pbctx
,
2
,
0
);
// FIXME: Wasted bytes field
...
...
@@ -79,6 +116,38 @@ static void write_frame_header(AlacEncodeContext *s, int is_verbatim)
put_bits
(
&
s
->
pbctx
,
32
,
s
->
avctx
->
frame_size
);
// No. of samples in the frame
}
static
int
estimate_stereo_mode
(
int32_t
*
left_ch
,
int32_t
*
right_ch
,
int
n
)
{
int
i
,
best
;
int32_t
lt
,
rt
;
uint64_t
sum
[
4
];
uint64_t
score
[
4
];
/* calculate sum of 2nd order residual for each channel */
sum
[
0
]
=
sum
[
1
]
=
sum
[
2
]
=
sum
[
3
]
=
0
;
for
(
i
=
2
;
i
<
n
;
i
++
)
{
lt
=
left_ch
[
i
]
-
2
*
left_ch
[
i
-
1
]
+
left_ch
[
i
-
2
];
rt
=
right_ch
[
i
]
-
2
*
right_ch
[
i
-
1
]
+
right_ch
[
i
-
2
];
sum
[
2
]
+=
FFABS
((
lt
+
rt
)
>>
1
);
sum
[
3
]
+=
FFABS
(
lt
-
rt
);
sum
[
0
]
+=
FFABS
(
lt
);
sum
[
1
]
+=
FFABS
(
rt
);
}
/* calculate score for each mode */
score
[
0
]
=
sum
[
0
]
+
sum
[
1
];
score
[
1
]
=
sum
[
0
]
+
sum
[
3
];
score
[
2
]
=
sum
[
1
]
+
sum
[
3
];
score
[
3
]
=
sum
[
2
]
+
sum
[
3
];
/* return mode with lowest score */
best
=
0
;
for
(
i
=
1
;
i
<
4
;
i
++
)
{
if
(
score
[
i
]
<
score
[
best
])
{
best
=
i
;
}
}
static
void
write_compressed_frame
(
AlacEncodeContext
*
s
)
{
int
i
,
j
;
...
...
@@ -88,7 +157,7 @@ static void write_compressed_frame(AlacEncodeContext *s)
put_bits
(
&
s
->
pbctx
,
8
,
s
->
interlacing_shift
);
put_bits
(
&
s
->
pbctx
,
8
,
s
->
interlacing_leftweight
);
for
(
i
=
0
;
i
<
s
->
channels
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
avctx
->
channels
;
i
++
)
{
calc_predictor_params
(
s
,
i
);
...
...
@@ -105,7 +174,7 @@ static void write_compressed_frame(AlacEncodeContext *s)
// apply lpc and entropy coding to audio samples
for
(
i
=
0
;
i
<
s
->
channels
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
avctx
->
channels
;
i
++
)
{
alac_linear_predictor
(
s
,
i
);
alac_entropy_coder
(
s
);
}
...
...
@@ -118,8 +187,6 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
avctx
->
frame_size
=
DEFAULT_FRAME_SIZE
;
avctx
->
bits_per_sample
=
DEFAULT_SAMPLE_SIZE
;
s
->
channels
=
avctx
->
channels
;
s
->
samplerate
=
avctx
->
sample_rate
;
if
(
avctx
->
sample_fmt
!=
SAMPLE_FMT_S16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"only pcm_s16 input samples are supported
\n
"
);
...
...
@@ -139,18 +206,18 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
s
->
rc
.
rice_modifier
=
4
;
s
->
max_coded_frame_size
=
(
ALAC_FRAME_HEADER_SIZE
+
ALAC_FRAME_FOOTER_SIZE
+
avctx
->
frame_size
*
s
->
channels
*
avctx
->
bits_per_sample
)
>>
3
;
avctx
->
frame_size
*
avctx
->
channels
*
avctx
->
bits_per_sample
)
>>
3
;
s
->
write_sample_size
=
avctx
->
bits_per_sample
+
s
->
channels
-
1
;
// FIXME: consider wasted_bytes
s
->
write_sample_size
=
avctx
->
bits_per_sample
+
avctx
->
channels
-
1
;
// FIXME: consider wasted_bytes
AV_WB32
(
alac_extradata
,
ALAC_EXTRADATA_SIZE
);
AV_WB32
(
alac_extradata
+
4
,
MKBETAG
(
'a'
,
'l'
,
'a'
,
'c'
));
AV_WB32
(
alac_extradata
+
12
,
avctx
->
frame_size
);
AV_WB8
(
alac_extradata
+
17
,
avctx
->
bits_per_sample
);
AV_WB8
(
alac_extradata
+
21
,
s
->
channels
);
AV_WB8
(
alac_extradata
+
21
,
avctx
->
channels
);
AV_WB32
(
alac_extradata
+
24
,
s
->
max_coded_frame_size
);
AV_WB32
(
alac_extradata
+
28
,
s
->
samplerate
*
s
->
channels
*
avctx
->
bits_per_sample
);
// average bitrate
AV_WB32
(
alac_extradata
+
32
,
s
->
sample
rate
);
AV_WB32
(
alac_extradata
+
28
,
avctx
->
sample_rate
*
avctx
->
channels
*
avctx
->
bits_per_sample
);
// average bitrate
AV_WB32
(
alac_extradata
+
32
,
avctx
->
sample_
rate
);
// Set relevant extradata fields
if
(
s
->
compression_level
>
0
)
{
...
...
@@ -168,19 +235,62 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
s
->
avctx
=
avctx
;
dsputil_init
(
&
s
->
dspctx
,
avctx
);
allocate_sample_buffers
(
s
);
return
0
;
}
static
av_cold
int
alac_encode_close
(
AVCodecContext
*
avctx
)
static
int
alac_encode_frame
(
AVCodecContext
*
avctx
,
uint8_t
*
frame
,
int
buf_size
,
void
*
data
)
{
AlacEncodeContext
*
s
=
avctx
->
priv_data
;
PutBitContext
*
pb
=
&
s
->
pbctx
;
int
i
,
out_bytes
,
verbatim_flag
=
0
;
if
(
avctx
->
frame_size
>
DEFAULT_FRAME_SIZE
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"input frame size exceeded
\n
"
);
return
-
1
;
}
if
(
buf_size
<
2
*
s
->
max_coded_frame_size
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"buffer size is too small
\n
"
);
return
-
1
;
}
if
((
s
->
compression_level
==
0
)
||
verbatim_flag
)
{
// Verbatim mode
int16_t
*
samples
=
data
;
write_frame_header
(
s
,
1
);
for
(
i
=
0
;
i
<
avctx
->
frame_size
*
avctx
->
channels
;
i
++
)
{
put_sbits
(
pb
,
16
,
*
samples
++
);
}
}
else
{
init_sample_buffers
(
s
,
data
);
write_frame_header
(
s
,
0
);
write_compressed_frame
(
s
);
}
put_bits
(
pb
,
3
,
7
);
flush_put_bits
(
pb
);
out_bytes
=
put_bits_count
(
pb
)
>>
3
;
if
(
out_bytes
>
s
->
max_coded_frame_size
)
{
/* frame too large. use verbatim mode */
if
(
verbatim_flag
||
(
s
->
compression_level
==
0
))
{
/* still too large. must be an error. */
av_log
(
avctx
,
AV_LOG_ERROR
,
"error encoding frame
\n
"
);
return
-
1
;
}
verbatim_flag
=
1
;
goto
verbatim
;
}
return
out_bytes
;
}
static
av_cold
int
alac_encode_close
(
AVCodecContext
*
avctx
)
{
av_freep
(
&
avctx
->
extradata
);
avctx
->
extradata_size
=
0
;
av_freep
(
&
avctx
->
coded_frame
);
free_sample_buffers
(
s
);
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录