Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
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