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
f61272f0
Commit
f61272f0
authored
Jan 12, 2013
by
Luca Barbato
Committed by
Diego Biurrun
Jan 12, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ratecontrol: K&R cosmetic formatting
Signed-off-by:
Diego Biurrun
<
diego@biurrun.de
>
parent
f6804c3e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
591 additions
and
486 deletions
+591
-486
ratecontrol.c
libavcodec/ratecontrol.c
+591
-486
No files found.
libavcodec/ratecontrol.c
View file @
f61272f0
...
...
@@ -40,34 +40,51 @@
#endif
static
int
init_pass2
(
MpegEncContext
*
s
);
static
double
get_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
rate_factor
,
int
frame_num
);
static
double
get_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
rate_factor
,
int
frame_num
);
void
ff_write_pass1_stats
(
MpegEncContext
*
s
){
snprintf
(
s
->
avctx
->
stats_out
,
256
,
"in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;
\n
"
,
s
->
current_picture_ptr
->
f
.
display_picture_number
,
s
->
current_picture_ptr
->
f
.
coded_picture_number
,
s
->
pict_type
,
s
->
current_picture
.
f
.
quality
,
s
->
i_tex_bits
,
s
->
p_tex_bits
,
s
->
mv_bits
,
s
->
misc_bits
,
s
->
f_code
,
s
->
b_code
,
s
->
current_picture
.
mc_mb_var_sum
,
s
->
current_picture
.
mb_var_sum
,
s
->
i_count
,
s
->
skip_count
,
s
->
header_bits
);
void
ff_write_pass1_stats
(
MpegEncContext
*
s
)
{
snprintf
(
s
->
avctx
->
stats_out
,
256
,
"in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d "
"fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;
\n
"
,
s
->
current_picture_ptr
->
f
.
display_picture_number
,
s
->
current_picture_ptr
->
f
.
coded_picture_number
,
s
->
pict_type
,
s
->
current_picture
.
f
.
quality
,
s
->
i_tex_bits
,
s
->
p_tex_bits
,
s
->
mv_bits
,
s
->
misc_bits
,
s
->
f_code
,
s
->
b_code
,
s
->
current_picture
.
mc_mb_var_sum
,
s
->
current_picture
.
mb_var_sum
,
s
->
i_count
,
s
->
skip_count
,
s
->
header_bits
);
}
static
inline
double
qp2bits
(
RateControlEntry
*
rce
,
double
qp
){
if
(
qp
<=
0
.
0
){
static
inline
double
qp2bits
(
RateControlEntry
*
rce
,
double
qp
)
{
if
(
qp
<=
0
.
0
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"qp<=0.0
\n
"
);
}
return
rce
->
qscale
*
(
double
)(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
1
)
/
qp
;
return
rce
->
qscale
*
(
double
)(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
1
)
/
qp
;
}
static
inline
double
bits2qp
(
RateControlEntry
*
rce
,
double
bits
){
if
(
bits
<
0
.
9
){
static
inline
double
bits2qp
(
RateControlEntry
*
rce
,
double
bits
)
{
if
(
bits
<
0
.
9
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"bits<0.9
\n
"
);
}
return
rce
->
qscale
*
(
double
)(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
1
)
/
bits
;
return
rce
->
qscale
*
(
double
)(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
1
)
/
bits
;
}
int
ff_rate_control_init
(
MpegEncContext
*
s
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
RateControlContext
*
rcc
=
&
s
->
rc_context
;
int
i
,
res
;
static
const
char
*
const
const_names
[]
=
{
static
const
char
*
const
const_names
[]
=
{
"PI"
,
"E"
,
"iTex"
,
...
...
@@ -83,10 +100,12 @@ int ff_rate_control_init(MpegEncContext *s)
"isB"
,
"avgQP"
,
"qComp"
,
/* "lastIQP",
#if 0
"lastIQP",
"lastPQP",
"lastBQP",
"nextNonBQP",*/
"nextNonBQP",
#endif
"avgIITex"
,
"avgPITex"
,
"avgPPTex"
,
...
...
@@ -94,156 +113,172 @@ int ff_rate_control_init(MpegEncContext *s)
"avgTex"
,
NULL
};
static
double
(
*
const
func1
[])(
void
*
,
double
)
=
{
static
double
(
*
const
func1
[])(
void
*
,
double
)
=
{
(
void
*
)
bits2qp
,
(
void
*
)
qp2bits
,
NULL
};
static
const
char
*
const
func1_names
[]
=
{
static
const
char
*
const
func1_names
[]
=
{
"bits2qp"
,
"qp2bits"
,
NULL
};
emms_c
();
res
=
av_expr_parse
(
&
rcc
->
rc_eq_eval
,
s
->
avctx
->
rc_eq
?
s
->
avctx
->
rc_eq
:
"tex^qComp"
,
const_names
,
func1_names
,
func1
,
NULL
,
NULL
,
0
,
s
->
avctx
);
res
=
av_expr_parse
(
&
rcc
->
rc_eq_eval
,
s
->
avctx
->
rc_eq
?
s
->
avctx
->
rc_eq
:
"tex^qComp"
,
const_names
,
func1_names
,
func1
,
NULL
,
NULL
,
0
,
s
->
avctx
);
if
(
res
<
0
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Error parsing rc_eq
\"
%s
\"\n
"
,
s
->
avctx
->
rc_eq
);
return
res
;
}
for
(
i
=
0
;
i
<
5
;
i
++
){
rcc
->
pred
[
i
].
coeff
=
FF_QP2LAMBDA
*
7
.
0
;
rcc
->
pred
[
i
].
count
=
1
.
0
;
rcc
->
pred
[
i
].
decay
=
0
.
4
;
rcc
->
i_cplx_sum
[
i
]
=
rcc
->
p_cplx_sum
[
i
]
=
rcc
->
mv_bits_sum
[
i
]
=
rcc
->
qscale_sum
[
i
]
=
rcc
->
frame_count
[
i
]
=
1
;
// 1 is better because of 1/0 and such
rcc
->
last_qscale_for
[
i
]
=
FF_QP2LAMBDA
*
5
;
for
(
i
=
0
;
i
<
5
;
i
++
)
{
rcc
->
pred
[
i
].
coeff
=
FF_QP2LAMBDA
*
7
.
0
;
rcc
->
pred
[
i
].
count
=
1
.
0
;
rcc
->
pred
[
i
].
decay
=
0
.
4
;
rcc
->
i_cplx_sum
[
i
]
=
rcc
->
p_cplx_sum
[
i
]
=
rcc
->
mv_bits_sum
[
i
]
=
rcc
->
qscale_sum
[
i
]
=
rcc
->
frame_count
[
i
]
=
1
;
// 1 is better because of 1/0 and such
rcc
->
last_qscale_for
[
i
]
=
FF_QP2LAMBDA
*
5
;
}
rcc
->
buffer_index
=
s
->
avctx
->
rc_initial_buffer_occupancy
;
rcc
->
buffer_index
=
s
->
avctx
->
rc_initial_buffer_occupancy
;
if
(
s
->
flags
&
CODEC_FLAG_PASS2
)
{
if
(
s
->
flags
&
CODEC_FLAG_PASS2
)
{
int
i
;
char
*
p
;
/* find number of pics */
p
=
s
->
avctx
->
stats_in
;
for
(
i
=-
1
;
p
;
i
++
){
p
=
strchr
(
p
+
1
,
';'
);
}
i
+=
s
->
max_b_frames
;
if
(
i
<=
0
||
i
>=
INT_MAX
/
sizeof
(
RateControlEntry
))
p
=
s
->
avctx
->
stats_in
;
for
(
i
=
-
1
;
p
;
i
++
)
p
=
strchr
(
p
+
1
,
';'
);
i
+=
s
->
max_b_frames
;
if
(
i
<=
0
||
i
>=
INT_MAX
/
sizeof
(
RateControlEntry
))
return
-
1
;
rcc
->
entry
=
av_mallocz
(
i
*
sizeof
(
RateControlEntry
));
rcc
->
num_entries
=
i
;
/* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
){
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
rce
->
pict_type
=
rce
->
new_pict_type
=
AV_PICTURE_TYPE_P
;
rce
->
qscale
=
rce
->
new_qscale
=
FF_QP2LAMBDA
*
2
;
rce
->
misc_bits
=
s
->
mb_num
+
10
;
rce
->
mb_var_sum
=
s
->
mb_num
*
100
;
rcc
->
entry
=
av_mallocz
(
i
*
sizeof
(
RateControlEntry
));
rcc
->
num_entries
=
i
;
/* init all to skipped p frames
* (with b frames we might have a not encoded frame at the end FIXME) */
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
rce
->
pict_type
=
rce
->
new_pict_type
=
AV_PICTURE_TYPE_P
;
rce
->
qscale
=
rce
->
new_qscale
=
FF_QP2LAMBDA
*
2
;
rce
->
misc_bits
=
s
->
mb_num
+
10
;
rce
->
mb_var_sum
=
s
->
mb_num
*
100
;
}
/* read stats */
p
=
s
->
avctx
->
stats_in
;
for
(
i
=
0
;
i
<
rcc
->
num_entries
-
s
->
max_b_frames
;
i
++
)
{
p
=
s
->
avctx
->
stats_in
;
for
(
i
=
0
;
i
<
rcc
->
num_entries
-
s
->
max_b_frames
;
i
++
)
{
RateControlEntry
*
rce
;
int
picture_number
;
int
e
;
char
*
next
;
next
=
strchr
(
p
,
';'
);
if
(
next
)
{
(
*
next
)
=
0
;
//sscanf in unbelievably slow on looong strings //
FIXME copy / do not write
next
=
strchr
(
p
,
';'
);
if
(
next
)
{
(
*
next
)
=
0
;
// sscanf in unbelievably slow on looong strings //
FIXME copy / do not write
next
++
;
}
e
=
sscanf
(
p
,
" in:%d "
,
&
picture_number
);
e
=
sscanf
(
p
,
" in:%d "
,
&
picture_number
);
assert
(
picture_number
>=
0
);
assert
(
picture_number
<
rcc
->
num_entries
);
rce
=
&
rcc
->
entry
[
picture_number
];
e
+=
sscanf
(
p
,
" in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d"
,
&
rce
->
pict_type
,
&
rce
->
qscale
,
&
rce
->
i_tex_bits
,
&
rce
->
p_tex_bits
,
&
rce
->
mv_bits
,
&
rce
->
misc_bits
,
&
rce
->
f_code
,
&
rce
->
b_code
,
&
rce
->
mc_mb_var_sum
,
&
rce
->
mb_var_sum
,
&
rce
->
i_count
,
&
rce
->
skip_count
,
&
rce
->
header_bits
);
if
(
e
!=
14
){
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"statistics are damaged at line %d, parser out=%d
\n
"
,
i
,
e
);
rce
=
&
rcc
->
entry
[
picture_number
];
e
+=
sscanf
(
p
,
" in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d"
,
&
rce
->
pict_type
,
&
rce
->
qscale
,
&
rce
->
i_tex_bits
,
&
rce
->
p_tex_bits
,
&
rce
->
mv_bits
,
&
rce
->
misc_bits
,
&
rce
->
f_code
,
&
rce
->
b_code
,
&
rce
->
mc_mb_var_sum
,
&
rce
->
mb_var_sum
,
&
rce
->
i_count
,
&
rce
->
skip_count
,
&
rce
->
header_bits
);
if
(
e
!=
14
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"statistics are damaged at line %d, parser out=%d
\n
"
,
i
,
e
);
return
-
1
;
}
p
=
next
;
p
=
next
;
}
if
(
init_pass2
(
s
)
<
0
)
return
-
1
;
if
(
init_pass2
(
s
)
<
0
)
return
-
1
;
//FIXME maybe move to end
if
((
s
->
flags
&
CODEC_FLAG_PASS2
)
&&
s
->
avctx
->
rc_strategy
==
FF_RC_STRATEGY_XVID
)
{
//
FIXME maybe move to end
if
((
s
->
flags
&
CODEC_FLAG_PASS2
)
&&
s
->
avctx
->
rc_strategy
==
FF_RC_STRATEGY_XVID
)
{
#if CONFIG_LIBXVID
return
ff_xvid_rate_control_init
(
s
);
#else
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Xvid ratecontrol requires libavcodec compiled with Xvid support.
\n
"
);
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Xvid ratecontrol requires libavcodec compiled with Xvid support.
\n
"
);
return
-
1
;
#endif
}
}
if
(
!
(
s
->
flags
&
CODEC_FLAG_PASS2
)){
if
(
!
(
s
->
flags
&
CODEC_FLAG_PASS2
))
{
rcc
->
short_term_qsum
=
0
.
001
;
rcc
->
short_term_qcount
=
0
.
001
;
rcc
->
short_term_qsum
=
0
.
001
;
rcc
->
short_term_qcount
=
0
.
001
;
rcc
->
pass1_rc_eq_output_sum
=
0
.
001
;
rcc
->
pass1_wanted_bits
=
0
.
001
;
rcc
->
pass1_rc_eq_output_sum
=
0
.
001
;
rcc
->
pass1_wanted_bits
=
0
.
001
;
if
(
s
->
avctx
->
qblur
>
1
.
0
){
if
(
s
->
avctx
->
qblur
>
1
.
0
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"qblur too large
\n
"
);
return
-
1
;
}
/* init stuff with the user specified complexity */
if
(
s
->
avctx
->
rc_initial_cplx
)
{
for
(
i
=
0
;
i
<
60
*
30
;
i
++
)
{
double
bits
=
s
->
avctx
->
rc_initial_cplx
*
(
i
/
10000
.
0
+
1
.
0
)
*
s
->
mb_num
;
if
(
s
->
avctx
->
rc_initial_cplx
)
{
for
(
i
=
0
;
i
<
60
*
30
;
i
++
)
{
double
bits
=
s
->
avctx
->
rc_initial_cplx
*
(
i
/
10000
.
0
+
1
.
0
)
*
s
->
mb_num
;
RateControlEntry
rce
;
if
(
i
%
((
s
->
gop_size
+
3
)
/
4
)
==
0
)
rce
.
pict_type
=
AV_PICTURE_TYPE_I
;
else
if
(
i
%
(
s
->
max_b_frames
+
1
))
rce
.
pict_type
=
AV_PICTURE_TYPE_B
;
else
rce
.
pict_type
=
AV_PICTURE_TYPE_P
;
rce
.
new_pict_type
=
rce
.
pict_type
;
rce
.
mc_mb_var_sum
=
bits
*
s
->
mb_num
/
100000
;
rce
.
mb_var_sum
=
s
->
mb_num
;
rce
.
qscale
=
FF_QP2LAMBDA
*
2
;
rce
.
f_code
=
2
;
rce
.
b_code
=
1
;
rce
.
misc_bits
=
1
;
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_I
){
rce
.
i_count
=
s
->
mb_num
;
rce
.
i_tex_bits
=
bits
;
rce
.
p_tex_bits
=
0
;
rce
.
mv_bits
=
0
;
}
else
{
rce
.
i_count
=
0
;
//FIXME we do know this approx
rce
.
i_tex_bits
=
0
;
rce
.
p_tex_bits
=
bits
*
0
.
9
;
rce
.
mv_bits
=
bits
*
0
.
1
;
if
(
i
%
((
s
->
gop_size
+
3
)
/
4
)
==
0
)
rce
.
pict_type
=
AV_PICTURE_TYPE_I
;
else
if
(
i
%
(
s
->
max_b_frames
+
1
))
rce
.
pict_type
=
AV_PICTURE_TYPE_B
;
else
rce
.
pict_type
=
AV_PICTURE_TYPE_P
;
rce
.
new_pict_type
=
rce
.
pict_type
;
rce
.
mc_mb_var_sum
=
bits
*
s
->
mb_num
/
100000
;
rce
.
mb_var_sum
=
s
->
mb_num
;
rce
.
qscale
=
FF_QP2LAMBDA
*
2
;
rce
.
f_code
=
2
;
rce
.
b_code
=
1
;
rce
.
misc_bits
=
1
;
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_I
)
{
rce
.
i_count
=
s
->
mb_num
;
rce
.
i_tex_bits
=
bits
;
rce
.
p_tex_bits
=
0
;
rce
.
mv_bits
=
0
;
}
else
{
rce
.
i_count
=
0
;
// FIXME we do know this approx
rce
.
i_tex_bits
=
0
;
rce
.
p_tex_bits
=
bits
*
0
.
9
;
rce
.
mv_bits
=
bits
*
0
.
1
;
}
rcc
->
i_cplx_sum
[
rce
.
pict_type
]
+=
rce
.
i_tex_bits
*
rce
.
qscale
;
rcc
->
p_cplx_sum
[
rce
.
pict_type
]
+=
rce
.
p_tex_bits
*
rce
.
qscale
;
rcc
->
i_cplx_sum
[
rce
.
pict_type
]
+=
rce
.
i_tex_bits
*
rce
.
qscale
;
rcc
->
p_cplx_sum
[
rce
.
pict_type
]
+=
rce
.
p_tex_bits
*
rce
.
qscale
;
rcc
->
mv_bits_sum
[
rce
.
pict_type
]
+=
rce
.
mv_bits
;
rcc
->
frame_count
[
rce
.
pict_type
]
++
;
rcc
->
frame_count
[
rce
.
pict_type
]
++
;
get_qscale
(
s
,
&
rce
,
rcc
->
pass1_wanted_bits
/
rcc
->
pass1_rc_eq_output_sum
,
i
);
get_qscale
(
s
,
&
rce
,
rcc
->
pass1_wanted_bits
/
rcc
->
pass1_rc_eq_output_sum
,
i
);
rcc
->
pass1_wanted_bits
+=
s
->
bit_rate
/
(
1
/
av_q2d
(
s
->
avctx
->
time_base
));
//FIXME misbehaves a little for variable fps
// FIXME misbehaves a little for variable fps
rcc
->
pass1_wanted_bits
+=
s
->
bit_rate
/
(
1
/
av_q2d
(
s
->
avctx
->
time_base
));
}
}
}
return
0
;
...
...
@@ -251,47 +286,49 @@ int ff_rate_control_init(MpegEncContext *s)
void
ff_rate_control_uninit
(
MpegEncContext
*
s
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
RateControlContext
*
rcc
=
&
s
->
rc_context
;
emms_c
();
av_expr_free
(
rcc
->
rc_eq_eval
);
av_freep
(
&
rcc
->
entry
);
#if CONFIG_LIBXVID
if
((
s
->
flags
&
CODEC_FLAG_PASS2
)
&&
s
->
avctx
->
rc_strategy
==
FF_RC_STRATEGY_XVID
)
if
((
s
->
flags
&
CODEC_FLAG_PASS2
)
&&
s
->
avctx
->
rc_strategy
==
FF_RC_STRATEGY_XVID
)
ff_xvid_rate_control_uninit
(
s
);
#endif
}
int
ff_vbv_update
(
MpegEncContext
*
s
,
int
frame_size
){
RateControlContext
*
rcc
=
&
s
->
rc_context
;
const
double
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
const
int
buffer_size
=
s
->
avctx
->
rc_buffer_size
;
const
double
min_rate
=
s
->
avctx
->
rc_min_rate
/
fps
;
const
double
max_rate
=
s
->
avctx
->
rc_max_rate
/
fps
;
int
ff_vbv_update
(
MpegEncContext
*
s
,
int
frame_size
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
const
double
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
const
int
buffer_size
=
s
->
avctx
->
rc_buffer_size
;
const
double
min_rate
=
s
->
avctx
->
rc_min_rate
/
fps
;
const
double
max_rate
=
s
->
avctx
->
rc_max_rate
/
fps
;
av_dlog
(
s
,
"%d %f %d %f %f
\n
"
,
buffer_size
,
rcc
->
buffer_index
,
frame_size
,
min_rate
,
max_rate
);
if
(
buffer_size
){
if
(
buffer_size
)
{
int
left
;
rcc
->
buffer_index
-=
frame_size
;
if
(
rcc
->
buffer_index
<
0
)
{
rcc
->
buffer_index
-=
frame_size
;
if
(
rcc
->
buffer_index
<
0
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"rc buffer underflow
\n
"
);
rcc
->
buffer_index
=
0
;
rcc
->
buffer_index
=
0
;
}
left
=
buffer_size
-
rcc
->
buffer_index
-
1
;
left
=
buffer_size
-
rcc
->
buffer_index
-
1
;
rcc
->
buffer_index
+=
av_clip
(
left
,
min_rate
,
max_rate
);
if
(
rcc
->
buffer_index
>
buffer_size
)
{
int
stuffing
=
ceil
((
rcc
->
buffer_index
-
buffer_size
)
/
8
);
if
(
rcc
->
buffer_index
>
buffer_size
)
{
int
stuffing
=
ceil
((
rcc
->
buffer_index
-
buffer_size
)
/
8
);
if
(
stuffing
<
4
&&
s
->
codec_id
==
AV_CODEC_ID_MPEG4
)
stuffing
=
4
;
rcc
->
buffer_index
-=
8
*
stuffing
;
if
(
stuffing
<
4
&&
s
->
codec_id
==
AV_CODEC_ID_MPEG4
)
stuffing
=
4
;
rcc
->
buffer_index
-=
8
*
stuffing
;
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"stuffing %d bytes
\n
"
,
stuffing
);
return
stuffing
;
...
...
@@ -303,34 +340,38 @@ int ff_vbv_update(MpegEncContext *s, int frame_size){
/**
* Modify the bitrate curve from pass1 for one frame.
*/
static
double
get_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
rate_factor
,
int
frame_num
){
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
static
double
get_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
rate_factor
,
int
frame_num
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
const
int
pict_type
=
rce
->
new_pict_type
;
const
double
mb_num
=
s
->
mb_num
;
double
q
,
bits
;
const
int
pict_type
=
rce
->
new_pict_type
;
const
double
mb_num
=
s
->
mb_num
;
int
i
;
double
const_values
[]
=
{
double
const_values
[]
=
{
M_PI
,
M_E
,
rce
->
i_tex_bits
*
rce
->
qscale
,
rce
->
p_tex_bits
*
rce
->
qscale
,
(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
)
*
(
double
)
rce
->
qscale
,
rce
->
mv_bits
/
mb_num
,
rce
->
pict_type
==
AV_PICTURE_TYPE_B
?
(
rce
->
f_code
+
rce
->
b_code
)
*
0
.
5
:
rce
->
f_code
,
rce
->
i_count
/
mb_num
,
rce
->
mc_mb_var_sum
/
mb_num
,
rce
->
mb_var_sum
/
mb_num
,
rce
->
i_tex_bits
*
rce
->
qscale
,
rce
->
p_tex_bits
*
rce
->
qscale
,
(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
)
*
(
double
)
rce
->
qscale
,
rce
->
mv_bits
/
mb_num
,
rce
->
pict_type
==
AV_PICTURE_TYPE_B
?
(
rce
->
f_code
+
rce
->
b_code
)
*
0
.
5
:
rce
->
f_code
,
rce
->
i_count
/
mb_num
,
rce
->
mc_mb_var_sum
/
mb_num
,
rce
->
mb_var_sum
/
mb_num
,
rce
->
pict_type
==
AV_PICTURE_TYPE_I
,
rce
->
pict_type
==
AV_PICTURE_TYPE_P
,
rce
->
pict_type
==
AV_PICTURE_TYPE_B
,
rcc
->
qscale_sum
[
pict_type
]
/
(
double
)
rcc
->
frame_count
[
pict_type
],
a
->
qcompress
,
/* rcc->last_qscale_for[AV_PICTURE_TYPE_I],
#if 0
rcc->last_qscale_for[AV_PICTURE_TYPE_I],
rcc->last_qscale_for[AV_PICTURE_TYPE_P],
rcc->last_qscale_for[AV_PICTURE_TYPE_B],
rcc->next_non_b_qscale,*/
rcc->next_non_b_qscale,
#endif
rcc
->
i_cplx_sum
[
AV_PICTURE_TYPE_I
]
/
(
double
)
rcc
->
frame_count
[
AV_PICTURE_TYPE_I
],
rcc
->
i_cplx_sum
[
AV_PICTURE_TYPE_P
]
/
(
double
)
rcc
->
frame_count
[
AV_PICTURE_TYPE_P
],
rcc
->
p_cplx_sum
[
AV_PICTURE_TYPE_P
]
/
(
double
)
rcc
->
frame_count
[
AV_PICTURE_TYPE_P
],
...
...
@@ -345,61 +386,71 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f
return
-
1
;
}
rcc
->
pass1_rc_eq_output_sum
+=
bits
;
bits
*=
rate_factor
;
if
(
bits
<
0
.
0
)
bits
=
0
.
0
;
bits
+=
1
.
0
;
//avoid 1/0 issues
rcc
->
pass1_rc_eq_output_sum
+=
bits
;
bits
*=
rate_factor
;
if
(
bits
<
0
.
0
)
bits
=
0
.
0
;
bits
+=
1
.
0
;
// avoid 1/0 issues
/* user override */
for
(
i
=
0
;
i
<
s
->
avctx
->
rc_override_count
;
i
++
){
RcOverride
*
rco
=
s
->
avctx
->
rc_override
;
if
(
rco
[
i
].
start_frame
>
frame_num
)
continue
;
if
(
rco
[
i
].
end_frame
<
frame_num
)
continue
;
if
(
rco
[
i
].
qscale
)
bits
=
qp2bits
(
rce
,
rco
[
i
].
qscale
);
//FIXME move at end to really force it?
for
(
i
=
0
;
i
<
s
->
avctx
->
rc_override_count
;
i
++
)
{
RcOverride
*
rco
=
s
->
avctx
->
rc_override
;
if
(
rco
[
i
].
start_frame
>
frame_num
)
continue
;
if
(
rco
[
i
].
end_frame
<
frame_num
)
continue
;
if
(
rco
[
i
].
qscale
)
bits
=
qp2bits
(
rce
,
rco
[
i
].
qscale
);
// FIXME move at end to really force it?
else
bits
*=
rco
[
i
].
quality_factor
;
bits
*=
rco
[
i
].
quality_factor
;
}
q
=
bits2qp
(
rce
,
bits
);
q
=
bits2qp
(
rce
,
bits
);
/* I/B difference */
if
(
pict_type
==
AV_PICTURE_TYPE_I
&&
s
->
avctx
->
i_quant_factor
<
0
.
0
)
q
=
-
q
*
s
->
avctx
->
i_quant_factor
+
s
->
avctx
->
i_quant_offset
;
else
if
(
pict_type
==
AV_PICTURE_TYPE_B
&&
s
->
avctx
->
b_quant_factor
<
0
.
0
)
q
=
-
q
*
s
->
avctx
->
b_quant_factor
+
s
->
avctx
->
b_quant_offset
;
if
(
q
<
1
)
q
=
1
;
if
(
pict_type
==
AV_PICTURE_TYPE_I
&&
s
->
avctx
->
i_quant_factor
<
0
.
0
)
q
=
-
q
*
s
->
avctx
->
i_quant_factor
+
s
->
avctx
->
i_quant_offset
;
else
if
(
pict_type
==
AV_PICTURE_TYPE_B
&&
s
->
avctx
->
b_quant_factor
<
0
.
0
)
q
=
-
q
*
s
->
avctx
->
b_quant_factor
+
s
->
avctx
->
b_quant_offset
;
if
(
q
<
1
)
q
=
1
;
return
q
;
}
static
double
get_diff_limited_q
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
q
){
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
const
int
pict_type
=
rce
->
new_pict_type
;
const
double
last_p_q
=
rcc
->
last_qscale_for
[
AV_PICTURE_TYPE_P
];
const
double
last_non_b_q
=
rcc
->
last_qscale_for
[
rcc
->
last_non_b_pict_type
];
if
(
pict_type
==
AV_PICTURE_TYPE_I
&&
(
a
->
i_quant_factor
>
0
.
0
||
rcc
->
last_non_b_pict_type
==
AV_PICTURE_TYPE_P
))
q
=
last_p_q
*
FFABS
(
a
->
i_quant_factor
)
+
a
->
i_quant_offset
;
else
if
(
pict_type
==
AV_PICTURE_TYPE_B
&&
a
->
b_quant_factor
>
0
.
0
)
q
=
last_non_b_q
*
a
->
b_quant_factor
+
a
->
b_quant_offset
;
if
(
q
<
1
)
q
=
1
;
static
double
get_diff_limited_q
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
q
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
const
int
pict_type
=
rce
->
new_pict_type
;
const
double
last_p_q
=
rcc
->
last_qscale_for
[
AV_PICTURE_TYPE_P
];
const
double
last_non_b_q
=
rcc
->
last_qscale_for
[
rcc
->
last_non_b_pict_type
];
if
(
pict_type
==
AV_PICTURE_TYPE_I
&&
(
a
->
i_quant_factor
>
0
.
0
||
rcc
->
last_non_b_pict_type
==
AV_PICTURE_TYPE_P
))
q
=
last_p_q
*
FFABS
(
a
->
i_quant_factor
)
+
a
->
i_quant_offset
;
else
if
(
pict_type
==
AV_PICTURE_TYPE_B
&&
a
->
b_quant_factor
>
0
.
0
)
q
=
last_non_b_q
*
a
->
b_quant_factor
+
a
->
b_quant_offset
;
if
(
q
<
1
)
q
=
1
;
/* last qscale / qdiff stuff */
if
(
rcc
->
last_non_b_pict_type
==
pict_type
||
pict_type
!=
AV_PICTURE_TYPE_I
){
double
last_q
=
rcc
->
last_qscale_for
[
pict_type
];
const
int
maxdiff
=
FF_QP2LAMBDA
*
a
->
max_qdiff
;
if
(
q
>
last_q
+
maxdiff
)
q
=
last_q
+
maxdiff
;
else
if
(
q
<
last_q
-
maxdiff
)
q
=
last_q
-
maxdiff
;
if
(
rcc
->
last_non_b_pict_type
==
pict_type
||
pict_type
!=
AV_PICTURE_TYPE_I
)
{
double
last_q
=
rcc
->
last_qscale_for
[
pict_type
];
const
int
maxdiff
=
FF_QP2LAMBDA
*
a
->
max_qdiff
;
if
(
q
>
last_q
+
maxdiff
)
q
=
last_q
+
maxdiff
;
else
if
(
q
<
last_q
-
maxdiff
)
q
=
last_q
-
maxdiff
;
}
rcc
->
last_qscale_for
[
pict_type
]
=
q
;
//
Note we cannot do that after blurring
rcc
->
last_qscale_for
[
pict_type
]
=
q
;
//
Note we cannot do that after blurring
if
(
pict_type
!=
AV_PICTURE_TYPE_B
)
rcc
->
last_non_b_pict_type
=
pict_type
;
if
(
pict_type
!=
AV_PICTURE_TYPE_B
)
rcc
->
last_non_b_pict_type
=
pict_type
;
return
q
;
}
...
...
@@ -407,239 +458,269 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl
/**
* Get the qmin & qmax for pict_type.
*/
static
void
get_qminmax
(
int
*
qmin_ret
,
int
*
qmax_ret
,
MpegEncContext
*
s
,
int
pict_type
){
int
qmin
=
s
->
avctx
->
lmin
;
int
qmax
=
s
->
avctx
->
lmax
;
static
void
get_qminmax
(
int
*
qmin_ret
,
int
*
qmax_ret
,
MpegEncContext
*
s
,
int
pict_type
)
{
int
qmin
=
s
->
avctx
->
lmin
;
int
qmax
=
s
->
avctx
->
lmax
;
assert
(
qmin
<=
qmax
);
if
(
pict_type
==
AV_PICTURE_TYPE_B
){
qmin
=
(
int
)(
qmin
*
FFABS
(
s
->
avctx
->
b_quant_factor
)
+
s
->
avctx
->
b_quant_offset
+
0
.
5
);
qmax
=
(
int
)(
qmax
*
FFABS
(
s
->
avctx
->
b_quant_factor
)
+
s
->
avctx
->
b_quant_offset
+
0
.
5
);
}
else
if
(
pict_type
==
AV_PICTURE_TYPE_I
){
qmin
=
(
int
)(
qmin
*
FFABS
(
s
->
avctx
->
i_quant_factor
)
+
s
->
avctx
->
i_quant_offset
+
0
.
5
);
qmax
=
(
int
)(
qmax
*
FFABS
(
s
->
avctx
->
i_quant_factor
)
+
s
->
avctx
->
i_quant_offset
+
0
.
5
);
switch
(
pict_type
)
{
case
AV_PICTURE_TYPE_B
:
qmin
=
(
int
)(
qmin
*
FFABS
(
s
->
avctx
->
b_quant_factor
)
+
s
->
avctx
->
b_quant_offset
+
0
.
5
);
qmax
=
(
int
)(
qmax
*
FFABS
(
s
->
avctx
->
b_quant_factor
)
+
s
->
avctx
->
b_quant_offset
+
0
.
5
);
break
;
case
AV_PICTURE_TYPE_I
:
qmin
=
(
int
)(
qmin
*
FFABS
(
s
->
avctx
->
i_quant_factor
)
+
s
->
avctx
->
i_quant_offset
+
0
.
5
);
qmax
=
(
int
)(
qmax
*
FFABS
(
s
->
avctx
->
i_quant_factor
)
+
s
->
avctx
->
i_quant_offset
+
0
.
5
);
break
;
}
qmin
=
av_clip
(
qmin
,
1
,
FF_LAMBDA_MAX
);
qmax
=
av_clip
(
qmax
,
1
,
FF_LAMBDA_MAX
);
qmin
=
av_clip
(
qmin
,
1
,
FF_LAMBDA_MAX
);
qmax
=
av_clip
(
qmax
,
1
,
FF_LAMBDA_MAX
);
if
(
qmax
<
qmin
)
qmax
=
qmin
;
if
(
qmax
<
qmin
)
qmax
=
qmin
;
*
qmin_ret
=
qmin
;
*
qmax_ret
=
qmax
;
*
qmin_ret
=
qmin
;
*
qmax_ret
=
qmax
;
}
static
double
modify_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
q
,
int
frame_num
){
RateControlContext
*
rcc
=
&
s
->
rc_context
;
static
double
modify_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
q
,
int
frame_num
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
const
double
buffer_size
=
s
->
avctx
->
rc_buffer_size
;
const
double
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
const
double
min_rate
=
s
->
avctx
->
rc_min_rate
/
fps
;
const
double
max_rate
=
s
->
avctx
->
rc_max_rate
/
fps
;
const
int
pict_type
=
rce
->
new_pict_type
;
int
qmin
,
qmax
;
const
int
pict_type
=
rce
->
new_pict_type
;
const
double
buffer_size
=
s
->
avctx
->
rc_buffer_size
;
const
double
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
const
double
min_rate
=
s
->
avctx
->
rc_min_rate
/
fps
;
const
double
max_rate
=
s
->
avctx
->
rc_max_rate
/
fps
;
get_qminmax
(
&
qmin
,
&
qmax
,
s
,
pict_type
);
/* modulation */
if
(
s
->
avctx
->
rc_qmod_freq
&&
frame_num
%
s
->
avctx
->
rc_qmod_freq
==
0
&&
pict_type
==
AV_PICTURE_TYPE_P
)
q
*=
s
->
avctx
->
rc_qmod_amp
;
if
(
s
->
avctx
->
rc_qmod_freq
&&
frame_num
%
s
->
avctx
->
rc_qmod_freq
==
0
&&
pict_type
==
AV_PICTURE_TYPE_P
)
q
*=
s
->
avctx
->
rc_qmod_amp
;
/* buffer overflow/underflow protection */
if
(
buffer_size
)
{
double
expected_size
=
rcc
->
buffer_index
;
if
(
buffer_size
)
{
double
expected_size
=
rcc
->
buffer_index
;
double
q_limit
;
if
(
min_rate
){
double
d
=
2
*
(
buffer_size
-
expected_size
)
/
buffer_size
;
if
(
d
>
1
.
0
)
d
=
1
.
0
;
else
if
(
d
<
0
.
0001
)
d
=
0
.
0001
;
q
*=
pow
(
d
,
1
.
0
/
s
->
avctx
->
rc_buffer_aggressivity
);
q_limit
=
bits2qp
(
rce
,
FFMAX
((
min_rate
-
buffer_size
+
rcc
->
buffer_index
)
*
s
->
avctx
->
rc_min_vbv_overflow_use
,
1
));
if
(
q
>
q_limit
){
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
){
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"limiting QP %f -> %f
\n
"
,
q
,
q_limit
);
}
q
=
q_limit
;
if
(
min_rate
)
{
double
d
=
2
*
(
buffer_size
-
expected_size
)
/
buffer_size
;
if
(
d
>
1
.
0
)
d
=
1
.
0
;
else
if
(
d
<
0
.
0001
)
d
=
0
.
0001
;
q
*=
pow
(
d
,
1
.
0
/
s
->
avctx
->
rc_buffer_aggressivity
);
q_limit
=
bits2qp
(
rce
,
FFMAX
((
min_rate
-
buffer_size
+
rcc
->
buffer_index
)
*
s
->
avctx
->
rc_min_vbv_overflow_use
,
1
));
if
(
q
>
q_limit
)
{
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"limiting QP %f -> %f
\n
"
,
q
,
q_limit
);
q
=
q_limit
;
}
}
if
(
max_rate
){
double
d
=
2
*
expected_size
/
buffer_size
;
if
(
d
>
1
.
0
)
d
=
1
.
0
;
else
if
(
d
<
0
.
0001
)
d
=
0
.
0001
;
q
/=
pow
(
d
,
1
.
0
/
s
->
avctx
->
rc_buffer_aggressivity
);
q_limit
=
bits2qp
(
rce
,
FFMAX
(
rcc
->
buffer_index
*
s
->
avctx
->
rc_max_available_vbv_use
,
1
));
if
(
q
<
q_limit
){
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
){
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"limiting QP %f -> %f
\n
"
,
q
,
q_limit
);
}
q
=
q_limit
;
if
(
max_rate
)
{
double
d
=
2
*
expected_size
/
buffer_size
;
if
(
d
>
1
.
0
)
d
=
1
.
0
;
else
if
(
d
<
0
.
0001
)
d
=
0
.
0001
;
q
/=
pow
(
d
,
1
.
0
/
s
->
avctx
->
rc_buffer_aggressivity
);
q_limit
=
bits2qp
(
rce
,
FFMAX
(
rcc
->
buffer_index
*
s
->
avctx
->
rc_max_available_vbv_use
,
1
));
if
(
q
<
q_limit
)
{
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"limiting QP %f -> %f
\n
"
,
q
,
q_limit
);
q
=
q_limit
;
}
}
}
av_dlog
(
s
,
"q:%f max:%f min:%f size:%f index:%f agr:%f
\n
"
,
q
,
max_rate
,
min_rate
,
buffer_size
,
rcc
->
buffer_index
,
s
->
avctx
->
rc_buffer_aggressivity
);
if
(
s
->
avctx
->
rc_qsquish
==
0
.
0
||
qmin
==
qmax
){
if
(
q
<
qmin
)
q
=
qmin
;
else
if
(
q
>
qmax
)
q
=
qmax
;
}
else
{
double
min2
=
log
(
qmin
);
double
max2
=
log
(
qmax
);
q
=
log
(
q
);
q
=
(
q
-
min2
)
/
(
max2
-
min2
)
-
0
.
5
;
q
*=
-
4
.
0
;
q
=
1
.
0
/
(
1
.
0
+
exp
(
q
));
q
=
q
*
(
max2
-
min2
)
+
min2
;
q
=
exp
(
q
);
if
(
s
->
avctx
->
rc_qsquish
==
0
.
0
||
qmin
==
qmax
)
{
if
(
q
<
qmin
)
q
=
qmin
;
else
if
(
q
>
qmax
)
q
=
qmax
;
}
else
{
double
min2
=
log
(
qmin
);
double
max2
=
log
(
qmax
);
q
=
log
(
q
);
q
=
(
q
-
min2
)
/
(
max2
-
min2
)
-
0
.
5
;
q
*=
-
4
.
0
;
q
=
1
.
0
/
(
1
.
0
+
exp
(
q
));
q
=
q
*
(
max2
-
min2
)
+
min2
;
q
=
exp
(
q
);
}
return
q
;
}
//----------------------------------
//
----------------------------------
// 1 Pass Code
static
double
predict_size
(
Predictor
*
p
,
double
q
,
double
var
)
{
return
p
->
coeff
*
var
/
(
q
*
p
->
count
);
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
<
10
)
return
;
double
new_coeff
=
size
*
q
/
(
var
+
1
);
if
(
var
<
10
)
return
;
p
->
count
*=
p
->
decay
;
p
->
coeff
*=
p
->
decay
;
p
->
count
*=
p
->
decay
;
p
->
coeff
*=
p
->
decay
;
p
->
count
++
;
p
->
coeff
+=
new_coeff
;
p
->
coeff
+=
new_coeff
;
}
static
void
adaptive_quantization
(
MpegEncContext
*
s
,
double
q
){
static
void
adaptive_quantization
(
MpegEncContext
*
s
,
double
q
)
{
int
i
;
const
float
lumi_masking
=
s
->
avctx
->
lumi_masking
/
(
128
.
0
*
128
.
0
);
const
float
dark_masking
=
s
->
avctx
->
dark_masking
/
(
128
.
0
*
128
.
0
);
const
float
temp_cplx_masking
=
s
->
avctx
->
temporal_cplx_masking
;
const
float
lumi_masking
=
s
->
avctx
->
lumi_masking
/
(
128
.
0
*
128
.
0
);
const
float
dark_masking
=
s
->
avctx
->
dark_masking
/
(
128
.
0
*
128
.
0
);
const
float
temp_cplx_masking
=
s
->
avctx
->
temporal_cplx_masking
;
const
float
spatial_cplx_masking
=
s
->
avctx
->
spatial_cplx_masking
;
const
float
p_masking
=
s
->
avctx
->
p_masking
;
const
float
border_masking
=
s
->
avctx
->
border_masking
;
float
bits_sum
=
0
.
0
;
float
cplx_sum
=
0
.
0
;
float
*
cplx_tab
=
s
->
cplx_tab
;
float
*
bits_tab
=
s
->
bits_tab
;
const
int
qmin
=
s
->
avctx
->
mb_lmin
;
const
int
qmax
=
s
->
avctx
->
mb_lmax
;
Picture
*
const
pic
=
&
s
->
current_picture
;
const
int
mb_width
=
s
->
mb_width
;
const
int
mb_height
=
s
->
mb_height
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
float
temp_cplx
=
sqrt
(
pic
->
mc_mb_var
[
mb_xy
]);
//
FIXME merge in pow()
float
spat_cplx
=
sqrt
(
pic
->
mb_var
[
mb_xy
]);
const
int
lumi
=
pic
->
mb_mean
[
mb_xy
];
const
float
p_masking
=
s
->
avctx
->
p_masking
;
const
float
border_masking
=
s
->
avctx
->
border_masking
;
float
bits_sum
=
0
.
0
;
float
cplx_sum
=
0
.
0
;
float
*
cplx_tab
=
s
->
cplx_tab
;
float
*
bits_tab
=
s
->
bits_tab
;
const
int
qmin
=
s
->
avctx
->
mb_lmin
;
const
int
qmax
=
s
->
avctx
->
mb_lmax
;
Picture
*
const
pic
=
&
s
->
current_picture
;
const
int
mb_width
=
s
->
mb_width
;
const
int
mb_height
=
s
->
mb_height
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
float
temp_cplx
=
sqrt
(
pic
->
mc_mb_var
[
mb_xy
]);
//
FIXME merge in pow()
float
spat_cplx
=
sqrt
(
pic
->
mb_var
[
mb_xy
]);
const
int
lumi
=
pic
->
mb_mean
[
mb_xy
];
float
bits
,
cplx
,
factor
;
int
mb_x
=
mb_xy
%
s
->
mb_stride
;
int
mb_y
=
mb_xy
/
s
->
mb_stride
;
int
mb_distance
;
float
mb_factor
=
0
.
0
;
if
(
spat_cplx
<
4
)
spat_cplx
=
4
;
//FIXME finetune
if
(
temp_cplx
<
4
)
temp_cplx
=
4
;
//FIXME finetune
if
((
s
->
mb_type
[
mb_xy
]
&
CANDIDATE_MB_TYPE_INTRA
)){
//FIXME hq mode
cplx
=
spat_cplx
;
factor
=
1
.
0
+
p_masking
;
}
else
{
cplx
=
temp_cplx
;
factor
=
pow
(
temp_cplx
,
-
temp_cplx_masking
);
if
(
spat_cplx
<
4
)
spat_cplx
=
4
;
// FIXME finetune
if
(
temp_cplx
<
4
)
temp_cplx
=
4
;
// FIXME finetune
if
((
s
->
mb_type
[
mb_xy
]
&
CANDIDATE_MB_TYPE_INTRA
))
{
// FIXME hq mode
cplx
=
spat_cplx
;
factor
=
1
.
0
+
p_masking
;
}
else
{
cplx
=
temp_cplx
;
factor
=
pow
(
temp_cplx
,
-
temp_cplx_masking
);
}
factor
*=
pow
(
spat_cplx
,
-
spatial_cplx_masking
);
factor
*=
pow
(
spat_cplx
,
-
spatial_cplx_masking
);
if
(
lumi
>
127
)
factor
*=
(
1
.
0
-
(
lumi
-
128
)
*
(
lumi
-
128
)
*
lumi_masking
);
if
(
lumi
>
127
)
factor
*=
(
1
.
0
-
(
lumi
-
128
)
*
(
lumi
-
128
)
*
lumi_masking
);
else
factor
*=
(
1
.
0
-
(
lumi
-
128
)
*
(
lumi
-
128
)
*
dark_masking
);
if
(
mb_x
<
mb_width
/
5
)
{
mb_distance
=
mb_width
/
5
-
mb_x
;
mb_factor
=
(
float
)
mb_distance
/
(
float
)(
mb_width
/
5
);
}
else
if
(
mb_x
>
4
*
mb_width
/
5
)
{
mb_distance
=
mb_x
-
4
*
mb_width
/
5
;
mb_factor
=
(
float
)
mb_distance
/
(
float
)(
mb_width
/
5
);
factor
*=
(
1
.
0
-
(
lumi
-
128
)
*
(
lumi
-
128
)
*
dark_masking
);
if
(
mb_x
<
mb_width
/
5
)
{
mb_distance
=
mb_width
/
5
-
mb_x
;
mb_factor
=
(
float
)
mb_distance
/
(
float
)(
mb_width
/
5
);
}
else
if
(
mb_x
>
4
*
mb_width
/
5
)
{
mb_distance
=
mb_x
-
4
*
mb_width
/
5
;
mb_factor
=
(
float
)
mb_distance
/
(
float
)(
mb_width
/
5
);
}
if
(
mb_y
<
mb_height
/
5
){
mb_distance
=
mb_height
/
5
-
mb_y
;
mb_factor
=
FFMAX
(
mb_factor
,
(
float
)
mb_distance
/
(
float
)(
mb_height
/
5
));
}
else
if
(
mb_y
>
4
*
mb_height
/
5
){
mb_distance
=
mb_y
-
4
*
mb_height
/
5
;
mb_factor
=
FFMAX
(
mb_factor
,
(
float
)
mb_distance
/
(
float
)(
mb_height
/
5
));
if
(
mb_y
<
mb_height
/
5
)
{
mb_distance
=
mb_height
/
5
-
mb_y
;
mb_factor
=
FFMAX
(
mb_factor
,
(
float
)
mb_distance
/
(
float
)(
mb_height
/
5
));
}
else
if
(
mb_y
>
4
*
mb_height
/
5
)
{
mb_distance
=
mb_y
-
4
*
mb_height
/
5
;
mb_factor
=
FFMAX
(
mb_factor
,
(
float
)
mb_distance
/
(
float
)(
mb_height
/
5
));
}
factor
*=
1
.
0
-
border_masking
*
mb_factor
;
factor
*=
1
.
0
-
border_masking
*
mb_factor
;
if
(
factor
<
0
.
00001
)
factor
=
0
.
00001
;
if
(
factor
<
0
.
00001
)
factor
=
0
.
00001
;
bits
=
cplx
*
factor
;
cplx_sum
+=
cplx
;
bits_sum
+=
bits
;
cplx_tab
[
i
]
=
cplx
;
bits_tab
[
i
]
=
bits
;
bits
=
cplx
*
factor
;
cplx_sum
+=
cplx
;
bits_sum
+=
bits
;
cplx_tab
[
i
]
=
cplx
;
bits_tab
[
i
]
=
bits
;
}
/* handle qmin/qmax clipping */
if
(
s
->
flags
&
CODEC_FLAG_NORMALIZE_AQP
)
{
float
factor
=
bits_sum
/
cplx_sum
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
float
newq
=
q
*
cplx_tab
[
i
]
/
bits_tab
[
i
];
newq
*=
factor
;
if
(
s
->
flags
&
CODEC_FLAG_NORMALIZE_AQP
)
{
float
factor
=
bits_sum
/
cplx_sum
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
float
newq
=
q
*
cplx_tab
[
i
]
/
bits_tab
[
i
];
newq
*=
factor
;
if
(
newq
>
qmax
)
{
if
(
newq
>
qmax
)
{
bits_sum
-=
bits_tab
[
i
];
cplx_sum
-=
cplx_tab
[
i
]
*
q
/
qmax
;
}
else
if
(
newq
<
qmin
){
cplx_sum
-=
cplx_tab
[
i
]
*
q
/
qmax
;
}
else
if
(
newq
<
qmin
)
{
bits_sum
-=
bits_tab
[
i
];
cplx_sum
-=
cplx_tab
[
i
]
*
q
/
qmin
;
cplx_sum
-=
cplx_tab
[
i
]
*
q
/
qmin
;
}
}
if
(
bits_sum
<
0
.
001
)
bits_sum
=
0
.
001
;
if
(
cplx_sum
<
0
.
001
)
cplx_sum
=
0
.
001
;
if
(
bits_sum
<
0
.
001
)
bits_sum
=
0
.
001
;
if
(
cplx_sum
<
0
.
001
)
cplx_sum
=
0
.
001
;
}
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
float
newq
=
q
*
cplx_tab
[
i
]
/
bits_tab
[
i
];
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
float
newq
=
q
*
cplx_tab
[
i
]
/
bits_tab
[
i
];
int
intq
;
if
(
s
->
flags
&
CODEC_FLAG_NORMALIZE_AQP
)
{
newq
*=
bits_sum
/
cplx_sum
;
if
(
s
->
flags
&
CODEC_FLAG_NORMALIZE_AQP
)
{
newq
*=
bits_sum
/
cplx_sum
;
}
intq
=
(
int
)(
newq
+
0
.
5
);
intq
=
(
int
)(
newq
+
0
.
5
);
if
(
intq
>
qmax
)
intq
=
qmax
;
else
if
(
intq
<
qmin
)
intq
=
qmin
;
s
->
lambda_table
[
mb_xy
]
=
intq
;
if
(
intq
>
qmax
)
intq
=
qmax
;
else
if
(
intq
<
qmin
)
intq
=
qmin
;
s
->
lambda_table
[
mb_xy
]
=
intq
;
}
}
void
ff_get_2pass_fcode
(
MpegEncContext
*
s
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
int
picture_number
=
s
->
picture_number
;
RateControlEntry
*
rce
;
void
ff_get_2pass_fcode
(
MpegEncContext
*
s
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
RateControlEntry
*
rce
=
&
rcc
->
entry
[
s
->
picture_number
]
;
rce
=
&
rcc
->
entry
[
picture_number
];
s
->
f_code
=
rce
->
f_code
;
s
->
b_code
=
rce
->
b_code
;
s
->
f_code
=
rce
->
f_code
;
s
->
b_code
=
rce
->
b_code
;
}
//FIXME rd or at least approx for dquant
//
FIXME rd or at least approx for dquant
float
ff_rate_estimate_qscale
(
MpegEncContext
*
s
,
int
dry_run
)
{
...
...
@@ -649,249 +730,272 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
double
diff
;
double
short_term_q
;
double
fps
;
int
picture_number
=
s
->
picture_number
;
int
picture_number
=
s
->
picture_number
;
int64_t
wanted_bits
;
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
RateControlEntry
local_rce
,
*
rce
;
double
bits
;
double
rate_factor
;
int
var
;
const
int
pict_type
=
s
->
pict_type
;
Picture
*
const
pic
=
&
s
->
current_picture
;
const
int
pict_type
=
s
->
pict_type
;
Picture
*
const
pic
=
&
s
->
current_picture
;
emms_c
();
#if CONFIG_LIBXVID
if
((
s
->
flags
&
CODEC_FLAG_PASS2
)
&&
s
->
avctx
->
rc_strategy
==
FF_RC_STRATEGY_XVID
)
if
((
s
->
flags
&
CODEC_FLAG_PASS2
)
&&
s
->
avctx
->
rc_strategy
==
FF_RC_STRATEGY_XVID
)
return
ff_xvid_rate_estimate_qscale
(
s
,
dry_run
);
#endif
get_qminmax
(
&
qmin
,
&
qmax
,
s
,
pict_type
);
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
/* update predictors */
if
(
picture_number
>
2
&&
!
dry_run
){
const
int
last_var
=
s
->
last_pict_type
==
AV_PICTURE_TYPE_I
?
rcc
->
last_mb_var_sum
:
rcc
->
last_mc_mb_var_sum
;
update_predictor
(
&
rcc
->
pred
[
s
->
last_pict_type
],
rcc
->
last_qscale
,
sqrt
(
last_var
),
s
->
frame_bits
);
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
/* update predictors */
if
(
picture_number
>
2
&&
!
dry_run
)
{
const
int
last_var
=
s
->
last_pict_type
==
AV_PICTURE_TYPE_I
?
rcc
->
last_mb_var_sum
:
rcc
->
last_mc_mb_var_sum
;
update_predictor
(
&
rcc
->
pred
[
s
->
last_pict_type
],
rcc
->
last_qscale
,
sqrt
(
last_var
),
s
->
frame_bits
);
}
if
(
s
->
flags
&
CODEC_FLAG_PASS2
)
{
assert
(
picture_number
>=
0
);
assert
(
picture_number
<
rcc
->
num_entries
);
rce
=
&
rcc
->
entry
[
picture_number
];
wanted_bits
=
rce
->
expected_bits
;
}
else
{
if
(
s
->
flags
&
CODEC_FLAG_PASS2
)
{
assert
(
picture_number
>=
0
);
assert
(
picture_number
<
rcc
->
num_entries
);
rce
=
&
rcc
->
entry
[
picture_number
];
wanted_bits
=
rce
->
expected_bits
;
}
else
{
Picture
*
dts_pic
;
rce
=
&
local_rce
;
rce
=
&
local_rce
;
//FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering
//but the reordering is simpler for now until h.264 b pyramid must be handeld
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
||
s
->
low_delay
)
dts_pic
=
s
->
current_picture_ptr
;
/* FIXME add a dts field to AVFrame and ensure it is set and use it
* here instead of reordering but the reordering is simpler for now
* until H.264 B-pyramid must be handled. */
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
||
s
->
low_delay
)
dts_pic
=
s
->
current_picture_ptr
;
else
dts_pic
=
s
->
last_picture_ptr
;
dts_pic
=
s
->
last_picture_ptr
;
if
(
!
dts_pic
||
dts_pic
->
f
.
pts
==
AV_NOPTS_VALUE
)
wanted_bits
=
(
uint64_t
)(
s
->
bit_rate
*
(
double
)
picture_number
/
fps
);
wanted_bits
=
(
uint64_t
)(
s
->
bit_rate
*
(
double
)
picture_number
/
fps
);
else
wanted_bits
=
(
uint64_t
)(
s
->
bit_rate
*
(
double
)
dts_pic
->
f
.
pts
/
fps
);
wanted_bits
=
(
uint64_t
)(
s
->
bit_rate
*
(
double
)
dts_pic
->
f
.
pts
/
fps
);
}
diff
=
s
->
total_bits
-
wanted_bits
;
br_compensation
=
(
a
->
bit_rate_tolerance
-
diff
)
/
a
->
bit_rate_tolerance
;
if
(
br_compensation
<=
0
.
0
)
br_compensation
=
0
.
001
;
diff
=
s
->
total_bits
-
wanted_bits
;
br_compensation
=
(
a
->
bit_rate_tolerance
-
diff
)
/
a
->
bit_rate_tolerance
;
if
(
br_compensation
<=
0
.
0
)
br_compensation
=
0
.
001
;
var
=
pict_type
==
AV_PICTURE_TYPE_I
?
pic
->
mb_var_sum
:
pic
->
mc_mb_var_sum
;
var
=
pict_type
==
AV_PICTURE_TYPE_I
?
pic
->
mb_var_sum
:
pic
->
mc_mb_var_sum
;
short_term_q
=
0
;
/* avoid warning */
if
(
s
->
flags
&
CODEC_FLAG_PASS2
)
{
if
(
pict_type
!=
AV_PICTURE_TYPE_I
)
if
(
s
->
flags
&
CODEC_FLAG_PASS2
)
{
if
(
pict_type
!=
AV_PICTURE_TYPE_I
)
assert
(
pict_type
==
rce
->
new_pict_type
);
q
=
rce
->
new_qscale
/
br_compensation
;
q
=
rce
->
new_qscale
/
br_compensation
;
av_dlog
(
s
,
"%f %f %f last:%d var:%d type:%d//
\n
"
,
q
,
rce
->
new_qscale
,
br_compensation
,
s
->
frame_bits
,
var
,
pict_type
);
}
else
{
rce
->
pict_type
=
rce
->
new_pict_type
=
pict_type
;
rce
->
mc_mb_var_sum
=
pic
->
mc_mb_var_sum
;
rce
->
mb_var_sum
=
pic
->
mb_var_sum
;
rce
->
qscale
=
FF_QP2LAMBDA
*
2
;
rce
->
f_code
=
s
->
f_code
;
rce
->
b_code
=
s
->
b_code
;
rce
->
misc_bits
=
1
;
bits
=
predict_size
(
&
rcc
->
pred
[
pict_type
],
rce
->
qscale
,
sqrt
(
var
));
if
(
pict_type
==
AV_PICTURE_TYPE_I
){
rce
->
i_count
=
s
->
mb_num
;
rce
->
i_tex_bits
=
bits
;
rce
->
p_tex_bits
=
0
;
rce
->
mv_bits
=
0
;
}
else
{
rce
->
i_count
=
0
;
//FIXME we do know this approx
rce
->
i_tex_bits
=
0
;
rce
->
p_tex_bits
=
bits
*
0
.
9
;
rce
->
mv_bits
=
bits
*
0
.
1
;
}
else
{
rce
->
pict_type
=
rce
->
new_pict_type
=
pict_type
;
rce
->
mc_mb_var_sum
=
pic
->
mc_mb_var_sum
;
rce
->
mb_var_sum
=
pic
->
mb_var_sum
;
rce
->
qscale
=
FF_QP2LAMBDA
*
2
;
rce
->
f_code
=
s
->
f_code
;
rce
->
b_code
=
s
->
b_code
;
rce
->
misc_bits
=
1
;
bits
=
predict_size
(
&
rcc
->
pred
[
pict_type
],
rce
->
qscale
,
sqrt
(
var
));
if
(
pict_type
==
AV_PICTURE_TYPE_I
)
{
rce
->
i_count
=
s
->
mb_num
;
rce
->
i_tex_bits
=
bits
;
rce
->
p_tex_bits
=
0
;
rce
->
mv_bits
=
0
;
}
else
{
rce
->
i_count
=
0
;
// FIXME we do know this approx
rce
->
i_tex_bits
=
0
;
rce
->
p_tex_bits
=
bits
*
0
.
9
;
rce
->
mv_bits
=
bits
*
0
.
1
;
}
rcc
->
i_cplx_sum
[
pict_type
]
+=
rce
->
i_tex_bits
*
rce
->
qscale
;
rcc
->
p_cplx_sum
[
pict_type
]
+=
rce
->
p_tex_bits
*
rce
->
qscale
;
rcc
->
i_cplx_sum
[
pict_type
]
+=
rce
->
i_tex_bits
*
rce
->
qscale
;
rcc
->
p_cplx_sum
[
pict_type
]
+=
rce
->
p_tex_bits
*
rce
->
qscale
;
rcc
->
mv_bits_sum
[
pict_type
]
+=
rce
->
mv_bits
;
rcc
->
frame_count
[
pict_type
]
++
;
rcc
->
frame_count
[
pict_type
]
++
;
bits
=
rce
->
i_tex_bits
+
rce
->
p_tex_bits
;
rate_factor
=
rcc
->
pass1_wanted_bits
/
rcc
->
pass1_rc_eq_output_sum
*
br_compensation
;
bits
=
rce
->
i_tex_bits
+
rce
->
p_tex_bits
;
rate_factor
=
rcc
->
pass1_wanted_bits
/
rcc
->
pass1_rc_eq_output_sum
*
br_compensation
;
q
=
get_qscale
(
s
,
rce
,
rate_factor
,
picture_number
);
q
=
get_qscale
(
s
,
rce
,
rate_factor
,
picture_number
);
if
(
q
<
0
)
return
-
1
;
assert
(
q
>
0
.
0
);
q
=
get_diff_limited_q
(
s
,
rce
,
q
);
assert
(
q
>
0
.
0
);
assert
(
q
>
0
.
0
);
q
=
get_diff_limited_q
(
s
,
rce
,
q
);
assert
(
q
>
0
.
0
);
if
(
pict_type
==
AV_PICTURE_TYPE_P
||
s
->
intra_only
){
//FIXME type dependent blur like in 2-pass
rcc
->
short_term_qsum
*=
a
->
qblur
;
rcc
->
short_term_qcount
*=
a
->
qblur
;
// FIXME type dependent blur like in 2-pass
if
(
pict_type
==
AV_PICTURE_TYPE_P
||
s
->
intra_only
)
{
rcc
->
short_term_qsum
*=
a
->
qblur
;
rcc
->
short_term_qcount
*=
a
->
qblur
;
rcc
->
short_term_qsum
+=
q
;
rcc
->
short_term_qsum
+=
q
;
rcc
->
short_term_qcount
++
;
q
=
short_term_q
=
rcc
->
short_term_qsum
/
rcc
->
short_term_qcount
;
q
=
short_term_q
=
rcc
->
short_term_qsum
/
rcc
->
short_term_qcount
;
}
assert
(
q
>
0
.
0
);
assert
(
q
>
0
.
0
);
q
=
modify_qscale
(
s
,
rce
,
q
,
picture_number
);
q
=
modify_qscale
(
s
,
rce
,
q
,
picture_number
);
rcc
->
pass1_wanted_bits
+=
s
->
bit_rate
/
fps
;
rcc
->
pass1_wanted_bits
+=
s
->
bit_rate
/
fps
;
assert
(
q
>
0
.
0
);
assert
(
q
>
0
.
0
);
}
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
){
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d
\n
"
,
av_get_picture_type_char
(
pict_type
),
qmin
,
q
,
qmax
,
picture_number
,
(
int
)
wanted_bits
/
1000
,
(
int
)
s
->
total_bits
/
1000
,
br_compensation
,
short_term_q
,
s
->
frame_bits
,
pic
->
mb_var_sum
,
pic
->
mc_mb_var_sum
,
s
->
bit_rate
/
1000
,
(
int
)
fps
);
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
{
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f "
"size:%d var:%d/%d br:%d fps:%d
\n
"
,
av_get_picture_type_char
(
pict_type
),
qmin
,
q
,
qmax
,
picture_number
,
(
int
)
wanted_bits
/
1000
,
(
int
)
s
->
total_bits
/
1000
,
br_compensation
,
short_term_q
,
s
->
frame_bits
,
pic
->
mb_var_sum
,
pic
->
mc_mb_var_sum
,
s
->
bit_rate
/
1000
,
(
int
)
fps
);
}
if
(
q
<
qmin
)
q
=
qmin
;
else
if
(
q
>
qmax
)
q
=
qmax
;
if
(
q
<
qmin
)
q
=
qmin
;
else
if
(
q
>
qmax
)
q
=
qmax
;
if
(
s
->
adaptive_quant
)
if
(
s
->
adaptive_quant
)
adaptive_quantization
(
s
,
q
);
else
q
=
(
int
)(
q
+
0
.
5
);
q
=
(
int
)(
q
+
0
.
5
);
if
(
!
dry_run
)
{
rcc
->
last_qscale
=
q
;
rcc
->
last_mc_mb_var_sum
=
pic
->
mc_mb_var_sum
;
rcc
->
last_mb_var_sum
=
pic
->
mb_var_sum
;
if
(
!
dry_run
)
{
rcc
->
last_qscale
=
q
;
rcc
->
last_mc_mb_var_sum
=
pic
->
mc_mb_var_sum
;
rcc
->
last_mb_var_sum
=
pic
->
mb_var_sum
;
}
return
q
;
}
//----------------------------------------------
//
----------------------------------------------
// 2-Pass code
static
int
init_pass2
(
MpegEncContext
*
s
)
{
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
RateControlContext
*
rcc
=
&
s
->
rc_context
;
AVCodecContext
*
a
=
s
->
avctx
;
int
i
,
toobig
;
double
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
double
complexity
[
5
]
=
{
0
,
0
,
0
,
0
,
0
};
// approximate bits at quant=1
uint64_t
const_bits
[
5
]
=
{
0
,
0
,
0
,
0
,
0
};
// quantizer independent bits
double
fps
=
1
/
av_q2d
(
s
->
avctx
->
time_base
);
double
complexity
[
5
]
=
{
0
};
// approximate bits at quant=1
uint64_t
const_bits
[
5
]
=
{
0
};
// quantizer independent bits
uint64_t
all_const_bits
;
uint64_t
all_available_bits
=
(
uint64_t
)(
s
->
bit_rate
*
(
double
)
rcc
->
num_entries
/
fps
);
double
rate_factor
=
0
;
uint64_t
all_available_bits
=
(
uint64_t
)(
s
->
bit_rate
*
(
double
)
rcc
->
num_entries
/
fps
);
double
rate_factor
=
0
;
double
step
;
//int last_i_frame=-10000000;
const
int
filter_size
=
(
int
)(
a
->
qblur
*
4
)
|
1
;
const
int
filter_size
=
(
int
)(
a
->
qblur
*
4
)
|
1
;
double
expected_bits
;
double
*
qscale
,
*
blurred_qscale
,
qscale_sum
;
/* find complexity & const_bits & decide the pict_types */
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
rce
->
new_pict_type
=
rce
->
pict_type
;
rcc
->
i_cplx_sum
[
rce
->
pict_type
]
+=
rce
->
i_tex_bits
*
rce
->
qscale
;
rcc
->
p_cplx_sum
[
rce
->
pict_type
]
+=
rce
->
p_tex_bits
*
rce
->
qscale
;
rce
->
new_pict_type
=
rce
->
pict_type
;
rcc
->
i_cplx_sum
[
rce
->
pict_type
]
+=
rce
->
i_tex_bits
*
rce
->
qscale
;
rcc
->
p_cplx_sum
[
rce
->
pict_type
]
+=
rce
->
p_tex_bits
*
rce
->
qscale
;
rcc
->
mv_bits_sum
[
rce
->
pict_type
]
+=
rce
->
mv_bits
;
rcc
->
frame_count
[
rce
->
pict_type
]
++
;
rcc
->
frame_count
[
rce
->
pict_type
]
++
;
complexity
[
rce
->
new_pict_type
]
+=
(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
)
*
(
double
)
rce
->
qscale
;
const_bits
[
rce
->
new_pict_type
]
+=
rce
->
mv_bits
+
rce
->
misc_bits
;
complexity
[
rce
->
new_pict_type
]
+=
(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
)
*
(
double
)
rce
->
qscale
;
const_bits
[
rce
->
new_pict_type
]
+=
rce
->
mv_bits
+
rce
->
misc_bits
;
}
all_const_bits
=
const_bits
[
AV_PICTURE_TYPE_I
]
+
const_bits
[
AV_PICTURE_TYPE_P
]
+
const_bits
[
AV_PICTURE_TYPE_B
];
if
(
all_available_bits
<
all_const_bits
){
all_const_bits
=
const_bits
[
AV_PICTURE_TYPE_I
]
+
const_bits
[
AV_PICTURE_TYPE_P
]
+
const_bits
[
AV_PICTURE_TYPE_B
];
if
(
all_available_bits
<
all_const_bits
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"requested bitrate is too low
\n
"
);
return
-
1
;
}
qscale
=
av_malloc
(
sizeof
(
double
)
*
rcc
->
num_entries
);
blurred_qscale
=
av_malloc
(
sizeof
(
double
)
*
rcc
->
num_entries
);
qscale
=
av_malloc
(
sizeof
(
double
)
*
rcc
->
num_entries
);
blurred_qscale
=
av_malloc
(
sizeof
(
double
)
*
rcc
->
num_entries
);
toobig
=
0
;
for
(
step
=
256
*
256
;
step
>
0
.
0000001
;
step
*=
0
.
5
)
{
expected_bits
=
0
;
rate_factor
+=
step
;
for
(
step
=
256
*
256
;
step
>
0
.
0000001
;
step
*=
0
.
5
)
{
expected_bits
=
0
;
rate_factor
+=
step
;
rcc
->
buffer_index
=
s
->
avctx
->
rc_buffer_size
/
2
;
rcc
->
buffer_index
=
s
->
avctx
->
rc_buffer_size
/
2
;
/* find qscale */
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
){
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
qscale
[
i
]
=
get_qscale
(
s
,
&
rcc
->
entry
[
i
],
rate_factor
,
i
);
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
qscale
[
i
]
=
get_qscale
(
s
,
&
rcc
->
entry
[
i
],
rate_factor
,
i
);
rcc
->
last_qscale_for
[
rce
->
pict_type
]
=
qscale
[
i
];
}
assert
(
filter_size
%
2
==
1
);
assert
(
filter_size
%
2
==
1
);
/* fixed I/B QP relative to P mode */
for
(
i
=
rcc
->
num_entries
-
1
;
i
>=
0
;
i
--
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
for
(
i
=
rcc
->
num_entries
-
1
;
i
>=
0
;
i
--
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
qscale
[
i
]
=
get_diff_limited_q
(
s
,
rce
,
qscale
[
i
]);
qscale
[
i
]
=
get_diff_limited_q
(
s
,
rce
,
qscale
[
i
]);
}
/* smooth curve */
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
const
int
pict_type
=
rce
->
new_pict_type
;
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
const
int
pict_type
=
rce
->
new_pict_type
;
int
j
;
double
q
=
0
.
0
,
sum
=
0
.
0
;
for
(
j
=
0
;
j
<
filter_size
;
j
++
){
int
index
=
i
+
j
-
filter_size
/
2
;
double
d
=
index
-
i
;
double
coeff
=
a
->
qblur
==
0
?
1
.
0
:
exp
(
-
d
*
d
/
(
a
->
qblur
*
a
->
qblur
));
if
(
index
<
0
||
index
>=
rcc
->
num_entries
)
continue
;
if
(
pict_type
!=
rcc
->
entry
[
index
].
new_pict_type
)
continue
;
q
+=
qscale
[
index
]
*
coeff
;
sum
+=
coeff
;
double
q
=
0
.
0
,
sum
=
0
.
0
;
for
(
j
=
0
;
j
<
filter_size
;
j
++
)
{
int
index
=
i
+
j
-
filter_size
/
2
;
double
d
=
index
-
i
;
double
coeff
=
a
->
qblur
==
0
?
1
.
0
:
exp
(
-
d
*
d
/
(
a
->
qblur
*
a
->
qblur
));
if
(
index
<
0
||
index
>=
rcc
->
num_entries
)
continue
;
if
(
pict_type
!=
rcc
->
entry
[
index
].
new_pict_type
)
continue
;
q
+=
qscale
[
index
]
*
coeff
;
sum
+=
coeff
;
}
blurred_qscale
[
i
]
=
q
/
sum
;
blurred_qscale
[
i
]
=
q
/
sum
;
}
/* find expected bits */
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
RateControlEntry
*
rce
=
&
rcc
->
entry
[
i
];
double
bits
;
rce
->
new_qscale
=
modify_qscale
(
s
,
rce
,
blurred_qscale
[
i
],
i
);
bits
=
qp2bits
(
rce
,
rce
->
new_qscale
)
+
rce
->
mv_bits
+
rce
->
misc_bits
;
bits
+=
8
*
ff_vbv_update
(
s
,
bits
);
rce
->
expected_bits
=
expected_bits
;
expected_bits
+=
bits
;
rce
->
new_qscale
=
modify_qscale
(
s
,
rce
,
blurred_qscale
[
i
],
i
);
bits
=
qp2bits
(
rce
,
rce
->
new_qscale
)
+
rce
->
mv_bits
+
rce
->
misc_bits
;
bits
+=
8
*
ff_vbv_update
(
s
,
bits
);
rce
->
expected_bits
=
expected_bits
;
expected_bits
+=
bits
;
}
av_dlog
(
s
->
avctx
,
"expected_bits: %f all_available_bits: %d rate_factor: %f
\n
"
,
expected_bits
,
(
int
)
all_available_bits
,
rate_factor
);
if
(
expected_bits
>
all_available_bits
)
{
rate_factor
-=
step
;
if
(
expected_bits
>
all_available_bits
)
{
rate_factor
-=
step
;
++
toobig
;
}
}
...
...
@@ -900,33 +1004,34 @@ static int init_pass2(MpegEncContext *s)
/* check bitrate calculations and print info */
qscale_sum
=
0
.
0
;
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
av_dlog
(
s
,
"[lavc rc] entry[%d].new_qscale = %.3f qp = %.3f
\n
"
,
i
,
rcc
->
entry
[
i
].
new_qscale
,
rcc
->
entry
[
i
].
new_qscale
/
FF_QP2LAMBDA
);
qscale_sum
+=
av_clip
(
rcc
->
entry
[
i
].
new_qscale
/
FF_QP2LAMBDA
,
s
->
avctx
->
qmin
,
s
->
avctx
->
qmax
);
qscale_sum
+=
av_clip
(
rcc
->
entry
[
i
].
new_qscale
/
FF_QP2LAMBDA
,
s
->
avctx
->
qmin
,
s
->
avctx
->
qmax
);
}
assert
(
toobig
<=
40
);
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"[lavc rc] requested bitrate: %d bps expected bitrate: %d bps
\n
"
,
s
->
bit_rate
,
(
int
)(
expected_bits
/
((
double
)
all_available_bits
/
s
->
bit_rate
)));
"[lavc rc] requested bitrate: %d bps expected bitrate: %d bps
\n
"
,
s
->
bit_rate
,
(
int
)(
expected_bits
/
((
double
)
all_available_bits
/
s
->
bit_rate
)));
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"[lavc rc] estimated target average qp: %.3f
\n
"
,
(
float
)
qscale_sum
/
rcc
->
num_entries
);
"[lavc rc] estimated target average qp: %.3f
\n
"
,
(
float
)
qscale_sum
/
rcc
->
num_entries
);
if
(
toobig
==
0
)
{
av_log
(
s
->
avctx
,
AV_LOG_INFO
,
"[lavc rc] Using all of requested bitrate is not "
"necessary for this video with these parameters.
\n
"
);
"[lavc rc] Using all of requested bitrate is not "
"necessary for this video with these parameters.
\n
"
);
}
else
if
(
toobig
==
40
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"[lavc rc] Error: bitrate too low for this video "
"with these parameters.
\n
"
);
"[lavc rc] Error: bitrate too low for this video "
"with these parameters.
\n
"
);
return
-
1
;
}
else
if
(
fabs
(
expected_bits
/
all_available_bits
-
1
.
0
)
>
0
.
01
)
{
}
else
if
(
fabs
(
expected_bits
/
all_available_bits
-
1
.
0
)
>
0
.
01
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"[lavc rc] Error: 2pass curve failed to converge
\n
"
);
"[lavc rc] Error: 2pass curve failed to converge
\n
"
);
return
-
1
;
}
...
...
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