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