Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
9cdd6a24
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,发现更多精彩内容 >>
提交
9cdd6a24
编写于
3月 17, 2002
作者:
M
Michael Niedermayer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hopefully better bitrate controll
Originally committed as revision 334 to
svn://svn.ffmpeg.org/ffmpeg/trunk
上级
1cb0edb4
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
258 addition
and
36 deletion
+258
-36
ffmpeg.c
ffmpeg.c
+64
-0
libavcodec/avcodec.h
libavcodec/avcodec.h
+7
-0
libavcodec/motion_est.c
libavcodec/motion_est.c
+1
-0
libavcodec/mpegvideo.c
libavcodec/mpegvideo.c
+162
-35
libavcodec/mpegvideo.h
libavcodec/mpegvideo.h
+24
-1
未找到文件。
ffmpeg.c
浏览文件 @
9cdd6a24
...
...
@@ -75,7 +75,13 @@ static int frame_width = 160;
static
int
frame_height
=
128
;
static
int
frame_rate
=
25
*
FRAME_RATE_BASE
;
static
int
video_bit_rate
=
200000
;
static
int
video_bit_rate_tolerance
=
200000
;
static
int
video_qscale
=
0
;
static
int
video_qmin
=
3
;
static
int
video_qmax
=
15
;
static
int
video_qdiff
=
3
;
static
float
video_qblur
=
0
.
5
;
static
float
video_qcomp
=
0
.
5
;
static
int
video_disable
=
0
;
static
int
video_codec_id
=
CODEC_ID_NONE
;
static
int
same_quality
=
0
;
...
...
@@ -1149,6 +1155,11 @@ void opt_video_bitrate(const char *arg)
video_bit_rate
=
atoi
(
arg
)
*
1000
;
}
void
opt_video_bitrate_tolerance
(
const
char
*
arg
)
{
video_bit_rate_tolerance
=
atoi
(
arg
)
*
1000
;
}
void
opt_frame_rate
(
const
char
*
arg
)
{
frame_rate
=
(
int
)(
strtod
(
arg
,
0
)
*
FRAME_RATE_BASE
);
...
...
@@ -1182,6 +1193,45 @@ void opt_qscale(const char *arg)
}
}
void
opt_qmin
(
const
char
*
arg
)
{
video_qmin
=
atoi
(
arg
);
if
(
video_qmin
<
0
||
video_qmin
>
31
)
{
fprintf
(
stderr
,
"qmin must be >= 1 and <= 31
\n
"
);
exit
(
1
);
}
}
void
opt_qmax
(
const
char
*
arg
)
{
video_qmax
=
atoi
(
arg
);
if
(
video_qmax
<
0
||
video_qmax
>
31
)
{
fprintf
(
stderr
,
"qmax must be >= 1 and <= 31
\n
"
);
exit
(
1
);
}
}
void
opt_qdiff
(
const
char
*
arg
)
{
video_qdiff
=
atoi
(
arg
);
if
(
video_qdiff
<
0
||
video_qdiff
>
31
)
{
fprintf
(
stderr
,
"qdiff must be >= 1 and <= 31
\n
"
);
exit
(
1
);
}
}
void
opt_qblur
(
const
char
*
arg
)
{
video_qblur
=
atof
(
arg
);
}
void
opt_qcomp
(
const
char
*
arg
)
{
video_qcomp
=
atof
(
arg
);
}
void
opt_audio_bitrate
(
const
char
*
arg
)
{
...
...
@@ -1611,6 +1661,7 @@ void opt_output_file(const char *filename)
video_enc
->
codec_type
=
CODEC_TYPE_VIDEO
;
video_enc
->
bit_rate
=
video_bit_rate
;
video_enc
->
bit_rate_tolerance
=
video_bit_rate_tolerance
;
video_enc
->
frame_rate
=
frame_rate
;
video_enc
->
width
=
frame_width
;
...
...
@@ -1623,6 +1674,13 @@ void opt_output_file(const char *filename)
video_enc
->
flags
|=
CODEC_FLAG_QSCALE
;
video_enc
->
quality
=
video_qscale
;
}
video_enc
->
qmin
=
video_qmin
;
video_enc
->
qmax
=
video_qmax
;
video_enc
->
max_qdiff
=
video_qdiff
;
video_enc
->
qblur
=
video_qblur
;
video_enc
->
qcompress
=
video_qcomp
;
if
(
do_psnr
)
video_enc
->
get_psnr
=
1
;
else
...
...
@@ -1948,6 +2006,12 @@ const OptionDef options[] = {
{
"intra"
,
OPT_BOOL
|
OPT_EXPERT
,
{(
void
*
)
&
intra_only
},
"use only intra frames"
},
{
"vn"
,
OPT_BOOL
,
{(
void
*
)
&
video_disable
},
"disable video"
},
{
"qscale"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_qscale
},
"use fixed video quantiser scale (VBR)"
,
"q"
},
{
"qmin"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_qmin
},
"min video quantiser scale (VBR)"
,
"q"
},
{
"qmax"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_qmax
},
"max video quantiser scale (VBR)"
,
"q"
},
{
"qdiff"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_qdiff
},
"max difference between the quantiser scale (VBR)"
,
"q"
},
{
"qblur"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_qblur
},
"video quantiser scale blur (VBR)"
,
"blur"
},
{
"qcomp"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_qcomp
},
"video quantiser scale compression (VBR)"
,
"compression"
},
{
"bt"
,
HAS_ARG
,
{(
void
*
)
opt_video_bitrate_tolerance
},
"set video bitrate tolerance (in kbit/s)"
,
"tolerance"
},
#ifdef CONFIG_GRAB
{
"vd"
,
HAS_ARG
|
OPT_EXPERT
,
{(
void
*
)
opt_video_device
},
"set video device"
,
"device"
},
#endif
...
...
libavcodec/avcodec.h
浏览文件 @
9cdd6a24
...
...
@@ -72,6 +72,7 @@ extern int motion_estimation_method;
typedef
struct
AVCodecContext
{
int
bit_rate
;
int
bit_rate_tolerance
;
/* amount of +- bits (>0)*/
int
flags
;
int
sub_id
;
/* some codecs needs additionnal format info. It is
stored there */
...
...
@@ -101,6 +102,12 @@ typedef struct AVCodecContext {
a key frame (intra, or seekable) */
int
quality
;
/* quality of the previous encoded frame
(between 1 (good) and 31 (bad)) */
float
qcompress
;
/* amount of qscale change between easy & hard scenes (0.0-1.0)*/
float
qblur
;
/* amount of qscale smoothing over time (0.0-1.0) */
int
qmin
;
/* min qscale */
int
qmax
;
/* max qscale */
int
max_qdiff
;
/* max qscale difference between frames */
struct
AVCodec
*
codec
;
void
*
priv_data
;
...
...
libavcodec/motion_est.c
浏览文件 @
9cdd6a24
...
...
@@ -460,6 +460,7 @@ int estimate_motion(MpegEncContext * s,
varc
=
(
varc
>>
8
)
-
(
sum
*
sum
);
s
->
mb_var
[
s
->
mb_width
*
mb_y
+
mb_x
]
=
varc
;
s
->
avg_mb_var
+=
varc
;
s
->
mc_mb_var
+=
vard
;
#if 0
printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",
...
...
libavcodec/mpegvideo.c
浏览文件 @
9cdd6a24
...
...
@@ -276,6 +276,7 @@ int MPV_encode_init(AVCodecContext *avctx)
int
i
;
s
->
bit_rate
=
avctx
->
bit_rate
;
s
->
bit_rate_tolerance
=
avctx
->
bit_rate_tolerance
;
s
->
frame_rate
=
avctx
->
frame_rate
;
s
->
width
=
avctx
->
width
;
s
->
height
=
avctx
->
height
;
...
...
@@ -284,6 +285,11 @@ int MPV_encode_init(AVCodecContext *avctx)
s
->
rtp_payload_size
=
avctx
->
rtp_payload_size
;
if
(
avctx
->
rtp_callback
)
s
->
rtp_callback
=
avctx
->
rtp_callback
;
s
->
qmin
=
avctx
->
qmin
;
s
->
qmax
=
avctx
->
qmax
;
s
->
max_qdiff
=
avctx
->
max_qdiff
;
s
->
qcompress
=
avctx
->
qcompress
;
s
->
qblur
=
avctx
->
qblur
;
s
->
avctx
=
avctx
;
if
(
s
->
gop_size
<=
1
)
{
...
...
@@ -520,7 +526,9 @@ int MPV_encode_picture(AVCodecContext *avctx,
mjpeg_picture_trailer
(
s
);
flush_put_bits
(
&
s
->
pb
);
s
->
total_bits
+=
(
pbBufPtr
(
&
s
->
pb
)
-
s
->
pb
.
buf
)
*
8
;
s
->
last_frame_bits
=
s
->
frame_bits
;
s
->
frame_bits
=
(
pbBufPtr
(
&
s
->
pb
)
-
s
->
pb
.
buf
)
*
8
;
s
->
total_bits
+=
s
->
frame_bits
;
avctx
->
quality
=
s
->
qscale
;
if
(
avctx
->
get_psnr
)
{
...
...
@@ -1040,6 +1048,36 @@ static void encode_picture(MpegEncContext *s, int picture_number)
int
i
,
motion_x
,
motion_y
;
s
->
picture_number
=
picture_number
;
s
->
last_mc_mb_var
=
s
->
mc_mb_var
;
/* Reset the average MB variance */
s
->
avg_mb_var
=
0
;
s
->
mc_mb_var
=
0
;
/* Estimate motion for every MB */
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
int
xy
=
mb_y
*
s
->
mb_width
+
mb_x
;
s
->
mb_x
=
mb_x
;
s
->
mb_y
=
mb_y
;
/* compute motion vector and macro block type (intra or non intra) */
motion_x
=
0
;
motion_y
=
0
;
if
(
s
->
pict_type
==
P_TYPE
)
{
s
->
mb_intra
=
estimate_motion
(
s
,
mb_x
,
mb_y
,
&
motion_x
,
&
motion_y
);
}
else
{
s
->
mb_intra
=
1
;
}
/* Store MB type and MV */
s
->
mb_type
[
xy
]
=
s
->
mb_intra
;
s
->
mv_table
[
0
][
xy
]
=
motion_x
;
s
->
mv_table
[
1
][
xy
]
=
motion_y
;
}
}
if
(
!
s
->
fixed_qscale
)
s
->
qscale
=
rate_estimate_qscale
(
s
);
...
...
@@ -1095,32 +1133,6 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s
->
gob_index
=
4
;
}
/* Reset the average MB variance */
s
->
avg_mb_var
=
0
;
/* Estimate motion for every MB */
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
s
->
mb_x
=
mb_x
;
s
->
mb_y
=
mb_y
;
/* compute motion vector and macro block type (intra or non intra) */
motion_x
=
0
;
motion_y
=
0
;
if
(
s
->
pict_type
==
P_TYPE
)
{
s
->
mb_intra
=
estimate_motion
(
s
,
mb_x
,
mb_y
,
&
motion_x
,
&
motion_y
);
}
else
{
s
->
mb_intra
=
1
;
}
/* Store MB type and MV */
s
->
mb_type
[
mb_y
*
s
->
mb_width
+
mb_x
]
=
s
->
mb_intra
;
s
->
mv_table
[
0
][
mb_y
*
s
->
mb_width
+
mb_x
]
=
motion_x
;
s
->
mv_table
[
1
][
mb_y
*
s
->
mb_width
+
mb_x
]
=
motion_y
;
}
}
s
->
avg_mb_var
=
s
->
avg_mb_var
/
s
->
mb_num
;
s
->
block_wrap
[
0
]
=
...
...
@@ -1542,6 +1554,22 @@ static void dct_unquantize_h263_c(MpegEncContext *s,
static
void
rate_control_init
(
MpegEncContext
*
s
)
{
#if 1
emms_c
();
//initial values, they dont really matter as they will be totally different within a few frames
s
->
i_pred
.
coeff
=
s
->
p_pred
.
coeff
=
7
.
0
;
s
->
i_pred
.
count
=
s
->
p_pred
.
count
=
1
.
0
;
s
->
i_pred
.
decay
=
s
->
p_pred
.
decay
=
0
.
4
;
// use more bits at the beginning, otherwise high motion at the begin will look like shit
s
->
qsum
=
100
;
s
->
qcount
=
100
;
s
->
short_term_qsum
=
0
.
001
;
s
->
short_term_qcount
=
0
.
001
;
#else
s
->
wanted_bits
=
0
;
if
(
s
->
intra_only
)
{
...
...
@@ -1557,19 +1585,117 @@ static void rate_control_init(MpegEncContext *s)
printf
(
"I_frame_size=%d P_frame_size=%d
\n
"
,
s
->
I_frame_bits
,
s
->
P_frame_bits
);
#endif
#endif
}
static
double
predict
(
Predictor
*
p
,
double
q
,
double
var
)
{
return
p
->
coeff
*
var
/
(
q
*
p
->
count
);
}
static
void
update_predictor
(
Predictor
*
p
,
double
q
,
double
var
,
double
size
)
{
double
new_coeff
=
size
*
q
/
(
var
+
1
);
if
(
var
<
1000
)
return
;
/*{
int pred= predict(p, q, var);
int error= abs(pred-size);
static double sum=0;
static int count=0;
if(count>5) sum+=error;
count++;
if(256*256*256*64%count==0){
printf("%d %f %f\n", count, sum/count, p->coeff);
}
}*/
p
->
count
*=
p
->
decay
;
p
->
coeff
*=
p
->
decay
;
p
->
count
++
;
p
->
coeff
+=
new_coeff
;
}
/*
* This heuristic is rather poor, but at least we do not have to
* change the qscale at every macroblock.
*/
static
int
rate_estimate_qscale
(
MpegEncContext
*
s
)
{
INT64
diff
,
total_bits
=
s
->
total_bits
;
#if 1
int
qmin
=
s
->
qmin
;
int
qmax
=
s
->
qmax
;
int
rate_q
=
5
;
float
q
;
int
qscale
,
qmin
;
int
qscale
;
float
br_compensation
;
double
diff
;
double
short_term_q
;
double
long_term_q
;
int
last_qscale
=
s
->
qscale
;
double
fps
;
INT64
wanted_bits
;
emms_c
();
fps
=
(
double
)
s
->
frame_rate
/
FRAME_RATE_BASE
;
wanted_bits
=
s
->
bit_rate
*
(
double
)
s
->
picture_number
/
fps
;
if
(
s
->
picture_number
>
2
){
/* update predictors */
if
(
s
->
last_pict_type
==
I_TYPE
){
//FIXME
}
else
{
//P Frame
//printf("%d %d %d %f\n", s->qscale, s->last_mc_mb_var, s->frame_bits, s->p_pred.coeff);
update_predictor
(
&
s
->
p_pred
,
s
->
qscale
,
s
->
last_mc_mb_var
,
s
->
frame_bits
);
}
}
if
(
s
->
pict_type
==
I_TYPE
){
//FIXME
rate_q
=
s
->
qsum
/
s
->
qcount
;
}
else
{
//P Frame
int
i
;
int
diff
,
best_diff
=
1000000000
;
for
(
i
=
1
;
i
<=
31
;
i
++
){
diff
=
predict
(
&
s
->
p_pred
,
i
,
s
->
mc_mb_var
)
-
(
double
)
s
->
bit_rate
/
fps
;
if
(
diff
<
0
)
diff
=
-
diff
;
if
(
diff
<
best_diff
){
best_diff
=
diff
;
rate_q
=
i
;
}
}
}
s
->
short_term_qsum
*=
s
->
qblur
;
s
->
short_term_qcount
*=
s
->
qblur
;
s
->
short_term_qsum
+=
rate_q
;
s
->
short_term_qcount
++
;
short_term_q
=
s
->
short_term_qsum
/
s
->
short_term_qcount
;
long_term_q
=
s
->
qsum
/
s
->
qcount
*
s
->
total_bits
/
wanted_bits
;
// q= (long_term_q - short_term_q)*s->qcompress + short_term_q;
q
=
1
/
((
1
/
long_term_q
-
1
/
short_term_q
)
*
s
->
qcompress
+
1
/
short_term_q
);
diff
=
s
->
total_bits
-
wanted_bits
;
br_compensation
=
(
s
->
bit_rate_tolerance
-
diff
)
/
s
->
bit_rate_tolerance
;
q
/=
br_compensation
;
qscale
=
(
int
)(
q
+
0
.
5
);
if
(
qscale
<
qmin
)
qscale
=
qmin
;
else
if
(
qscale
>
qmax
)
qscale
=
qmax
;
if
(
qscale
<
last_qscale
-
s
->
max_qdiff
)
qscale
=
last_qscale
-
s
->
max_qdiff
;
else
if
(
qscale
>
last_qscale
+
s
->
max_qdiff
)
qscale
=
last_qscale
+
s
->
max_qdiff
;
s
->
qsum
+=
qscale
;
s
->
qcount
++
;
s
->
last_pict_type
=
s
->
pict_type
;
//printf("q:%d diff:%d comp:%f rate_q:%d st_q:%d fvar:%d last_size:%d\n", qscale, (int)diff, br_compensation,
// rate_q, (int)short_term_q, s->mc_mb_var, s->frame_bits);
//printf("%d %d\n", s->bit_rate, (int)fps);
return
qscale
;
#else
INT64
diff
,
total_bits
=
s
->
total_bits
;
float
q
;
int
qscale
;
if
(
s
->
pict_type
==
I_TYPE
)
{
s
->
wanted_bits
+=
s
->
I_frame_bits
;
}
else
{
...
...
@@ -1600,6 +1726,7 @@ static int rate_estimate_qscale(MpegEncContext *s)
(
int
)
diff
,
q
);
#endif
return
qscale
;
#endif
}
AVCodec
mpeg1video_encoder
=
{
...
...
libavcodec/mpegvideo.h
浏览文件 @
9cdd6a24
...
...
@@ -34,6 +34,12 @@ enum OutputFormat {
#define QMAT_SHIFT_MMX 19
#define QMAT_SHIFT 25
typedef
struct
Predictor
{
double
coeff
;
double
count
;
double
decay
;
}
Predictor
;
typedef
struct
MpegEncContext
{
struct
AVCodecContext
*
avctx
;
/* the following parameters must be initialized before encoding */
...
...
@@ -42,6 +48,7 @@ typedef struct MpegEncContext {
int
frame_rate
;
/* number of frames per second */
int
intra_only
;
/* if true, only intra pictures are generated */
int
bit_rate
;
/* wanted bit rate */
int
bit_rate_tolerance
;
/* amount of +- bits (>0)*/
enum
OutputFormat
out_format
;
/* output format */
int
h263_plus
;
/* h263 plus headers */
int
h263_rv10
;
/* use RV10 variation for H263 */
...
...
@@ -49,6 +56,11 @@ typedef struct MpegEncContext {
int
h263_msmpeg4
;
/* generate MSMPEG4 compatible stream */
int
h263_intel
;
/* use I263 intel h263 header */
int
fixed_qscale
;
/* fixed qscale if non zero */
float
qcompress
;
/* amount of qscale change between easy & hard scenes (0.0-1.0) */
float
qblur
;
/* amount of qscale smoothing over time (0.0-1.0) */
int
qmin
;
/* min qscale */
int
qmax
;
/* max qscale */
int
max_qdiff
;
/* max qscale difference between frames */
int
encoding
;
/* true if we are encoding (vs decoding) */
/* the following fields are managed internally by the encoder */
...
...
@@ -85,6 +97,7 @@ typedef struct MpegEncContext {
int
qscale
;
int
pict_type
;
int
last_non_b_pict_type
;
/* used for mpeg4 gmc b-frames */
int
last_pict_type
;
/* used for bit rate stuff (needs that to update the right predictor) */
int
frame_rate_index
;
/* motion compensation */
int
unrestricted_mv
;
...
...
@@ -146,8 +159,18 @@ typedef struct MpegEncContext {
int
I_frame_bits
;
/* wanted number of bits per I frame */
int
P_frame_bits
;
/* same for P frame */
int
avg_mb_var
;
/* average MB variance for current frame */
int
mc_mb_var
;
/* motion compensated MB variance for current frame */
int
last_mc_mb_var
;
/* motion compensated MB variance for last frame */
INT64
wanted_bits
;
INT64
total_bits
;
int
frame_bits
;
/* bits used for the current frame */
int
last_frame_bits
;
/* bits used for the last frame */
Predictor
i_pred
;
Predictor
p_pred
;
double
qsum
;
/* sum of qscales */
double
qcount
;
/* count of qscales */
double
short_term_qsum
;
/* sum of recent qscales */
double
short_term_qcount
;
/* count of recent qscales */
/* H.263 specific */
int
gob_number
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录