Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
a1f6a2df
Commit
a1f6a2df
authored
Jul 20, 2016
by
Vittorio Giovara
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ratecontrol: Reorder functions to avoid forward declarations
parent
d639dcda
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
430 additions
and
440 deletions
+430
-440
ratecontrol.c
libavcodec/ratecontrol.c
+430
-440
No files found.
libavcodec/ratecontrol.c
View file @
a1f6a2df
...
@@ -42,24 +42,406 @@
...
@@ -42,24 +42,406 @@
#define M_E 2.718281828
#define M_E 2.718281828
#endif
#endif
static
int
init_pass2
(
MpegEncContext
*
s
);
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
;
}
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
;
}
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
;
}
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
;
return
q
;
}
/**
* 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
->
lmin
;
int
qmax
=
s
->
lmax
;
assert
(
qmin
<=
qmax
);
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
);
if
(
qmax
<
qmin
)
qmax
=
qmin
;
*
qmin_ret
=
qmin
;
*
qmax_ret
=
qmax
;
}
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
;
get_qminmax
(
&
qmin
,
&
qmax
,
s
,
pict_type
);
/* modulation */
if
(
s
->
rc_qmod_freq
&&
frame_num
%
s
->
rc_qmod_freq
==
0
&&
pict_type
==
AV_PICTURE_TYPE_P
)
q
*=
s
->
rc_qmod_amp
;
/* buffer overflow/underflow protection */
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
->
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
->
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
;
}
}
}
ff_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
->
rc_buffer_aggressivity
);
if
(
s
->
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
;
}
/**
* Modify the bitrate curve from pass1 for one frame.
*/
static
double
get_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
static
double
get_qscale
(
MpegEncContext
*
s
,
RateControlEntry
*
rce
,
double
rate_factor
,
int
frame_num
);
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
;
int
i
;
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
->
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
->
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
],
rcc
->
p_cplx_sum
[
AV_PICTURE_TYPE_B
]
/
(
double
)
rcc
->
frame_count
[
AV_PICTURE_TYPE_B
],
(
rcc
->
i_cplx_sum
[
pict_type
]
+
rcc
->
p_cplx_sum
[
pict_type
])
/
(
double
)
rcc
->
frame_count
[
pict_type
],
0
};
bits
=
av_expr_eval
(
rcc
->
rc_eq_eval
,
const_values
,
rce
);
if
(
isnan
(
bits
))
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Error evaluating rc_eq
\"
%s
\"\n
"
,
s
->
rc_eq
);
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
/* 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?
else
bits
*=
rco
[
i
].
quality_factor
;
}
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
;
return
q
;
}
static
int
init_pass2
(
MpegEncContext
*
s
)
{
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
};
// 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
;
double
step
;
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
];
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
]
++
;
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
)
{
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
);
if
(
!
qscale
||
!
blurred_qscale
)
{
av_free
(
qscale
);
av_free
(
blurred_qscale
);
return
AVERROR
(
ENOMEM
);
}
toobig
=
0
;
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
;
/* 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
);
rcc
->
last_qscale_for
[
rce
->
pict_type
]
=
qscale
[
i
];
}
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
];
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
;
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
;
}
blurred_qscale
[
i
]
=
q
/
sum
;
}
/* find expected bits */
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
;
}
static
inline
double
qp2bits
(
RateControlEntry
*
rce
,
double
qp
)
ff_dlog
(
s
->
avctx
,
{
"expected_bits: %f all_available_bits: %d rate_factor: %f
\n
"
,
if
(
qp
<=
0
.
0
)
{
expected_bits
,
(
int
)
all_available_bits
,
rate_factor
);
av_log
(
NULL
,
AV_LOG_ERROR
,
"qp<=0.0
\n
"
);
if
(
expected_bits
>
all_available_bits
)
{
rate_factor
-=
step
;
++
toobig
;
}
}
}
return
rce
->
qscale
*
(
double
)(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
1
)
/
qp
;
av_free
(
qscale
)
;
}
av_free
(
blurred_qscale
);
static
inline
double
bits2qp
(
RateControlEntry
*
rce
,
double
bits
)
/* check bitrate calculations and print info */
{
qscale_sum
=
0
.
0
;
if
(
bits
<
0
.
9
)
{
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"bits<0.9
\n
"
);
ff_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
);
}
}
return
rce
->
qscale
*
(
double
)(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
1
)
/
bits
;
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
)));
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"[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
"
);
}
else
if
(
toobig
==
40
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"[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
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"[lavc rc] Error: 2pass curve failed to converge
\n
"
);
return
-
1
;
}
return
0
;
}
}
av_cold
int
ff_rate_control_init
(
MpegEncContext
*
s
)
av_cold
int
ff_rate_control_init
(
MpegEncContext
*
s
)
...
@@ -253,288 +635,54 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
...
@@ -253,288 +635,54 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
return
0
;
return
0
;
}
}
av_cold
void
ff_rate_control_uninit
(
MpegEncContext
*
s
)
av_cold
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_freep
(
&
rcc
->
entry
);
}
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
;
ff_dlog
(
s
,
"%d %f %d %f %f
\n
"
,
buffer_size
,
rcc
->
buffer_index
,
frame_size
,
min_rate
,
max_rate
);
if
(
buffer_size
)
{
int
left
;
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
;
}
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
(
stuffing
<
4
&&
s
->
codec_id
==
AV_CODEC_ID_MPEG4
)
stuffing
=
4
;
rcc
->
buffer_index
-=
8
*
stuffing
;
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"stuffing %d bytes
\n
"
,
stuffing
);
return
stuffing
;
}
}
return
0
;
}
/**
* 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
;
const
int
pict_type
=
rce
->
new_pict_type
;
const
double
mb_num
=
s
->
mb_num
;
double
q
,
bits
;
int
i
;
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
->
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
->
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
],
rcc
->
p_cplx_sum
[
AV_PICTURE_TYPE_B
]
/
(
double
)
rcc
->
frame_count
[
AV_PICTURE_TYPE_B
],
(
rcc
->
i_cplx_sum
[
pict_type
]
+
rcc
->
p_cplx_sum
[
pict_type
])
/
(
double
)
rcc
->
frame_count
[
pict_type
],
0
};
bits
=
av_expr_eval
(
rcc
->
rc_eq_eval
,
const_values
,
rce
);
if
(
isnan
(
bits
))
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Error evaluating rc_eq
\"
%s
\"\n
"
,
s
->
rc_eq
);
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
/* 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?
else
bits
*=
rco
[
i
].
quality_factor
;
}
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
;
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
;
/* 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
;
}
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
;
return
q
;
}
/**
* 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
->
lmin
;
int
qmax
=
s
->
lmax
;
assert
(
qmin
<=
qmax
);
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
);
if
(
qmax
<
qmin
)
qmax
=
qmin
;
*
qmin_ret
=
qmin
;
*
qmax_ret
=
qmax
;
}
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
;
get_qminmax
(
&
qmin
,
&
qmax
,
s
,
pict_type
);
/* modulation */
av_expr_free
(
rcc
->
rc_eq_eval
);
if
(
s
->
rc_qmod_freq
&&
av_freep
(
&
rcc
->
entry
);
frame_num
%
s
->
rc_qmod_freq
==
0
&&
}
pict_type
==
AV_PICTURE_TYPE_P
)
q
*=
s
->
rc_qmod_amp
;
/* buffer overflow/underflow protection */
int
ff_vbv_update
(
MpegEncContext
*
s
,
int
frame_size
)
if
(
buffer_size
)
{
{
double
expected_size
=
rcc
->
buffer_index
;
RateControlContext
*
rcc
=
&
s
->
rc_context
;
double
q_limit
;
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
;
if
(
min_rate
)
{
ff_dlog
(
s
,
"%d %f %d %f %f
\n
"
,
double
d
=
2
*
(
buffer_size
-
expected_size
)
/
buffer_size
;
buffer_size
,
rcc
->
buffer_index
,
frame_size
,
min_rate
,
max_rate
);
if
(
d
>
1
.
0
)
d
=
1
.
0
;
else
if
(
d
<
0
.
0001
)
d
=
0
.
0001
;
q
*=
pow
(
d
,
1
.
0
/
s
->
rc_buffer_aggressivity
);
q_limit
=
bits2qp
(
rce
,
if
(
buffer_size
)
{
FFMAX
((
min_rate
-
buffer_size
+
rcc
->
buffer_index
)
*
int
left
;
s
->
avctx
->
rc_min_vbv_overflow_use
,
1
));
if
(
q
>
q_limit
)
{
rcc
->
buffer_index
-=
frame_size
;
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
if
(
rcc
->
buffer_index
<
0
)
{
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"rc buffer underflow
\n
"
);
"limiting QP %f -> %f
\n
"
,
q
,
q_limit
);
rcc
->
buffer_index
=
0
;
q
=
q_limit
;
}
}
}
if
(
max_rate
)
{
left
=
buffer_size
-
rcc
->
buffer_index
-
1
;
double
d
=
2
*
expected_size
/
buffer_size
;
rcc
->
buffer_index
+=
av_clip
(
left
,
min_rate
,
max_rate
);
if
(
d
>
1
.
0
)
d
=
1
.
0
;
else
if
(
d
<
0
.
0001
)
d
=
0
.
0001
;
q
/=
pow
(
d
,
1
.
0
/
s
->
rc_buffer_aggressivity
);
q_limit
=
bits2qp
(
rce
,
if
(
rcc
->
buffer_index
>
buffer_size
)
{
FFMAX
(
rcc
->
buffer_index
*
int
stuffing
=
ceil
((
rcc
->
buffer_index
-
buffer_size
)
/
8
);
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
;
}
}
}
ff_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
->
rc_buffer_aggressivity
);
if
(
s
->
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
);
if
(
stuffing
<
4
&&
s
->
codec_id
==
AV_CODEC_ID_MPEG4
)
q
=
(
q
-
min2
)
/
(
max2
-
min2
)
-
0
.
5
;
stuffing
=
4
;
q
*=
-
4
.
0
;
rcc
->
buffer_index
-=
8
*
stuffing
;
q
=
1
.
0
/
(
1
.
0
+
exp
(
q
));
q
=
q
*
(
max2
-
min2
)
+
min2
;
q
=
exp
(
q
);
if
(
s
->
avctx
->
debug
&
FF_DEBUG_RC
)
}
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"stuffing %d bytes
\n
"
,
stuffing
);
return
q
;
return
stuffing
;
}
}
return
0
;
}
}
// ----------------------------------
// 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
);
...
@@ -836,161 +984,3 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
...
@@ -836,161 +984,3 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
}
}
return
q
;
return
q
;
}
}
// ----------------------------------------------
// 2-Pass code
static
int
init_pass2
(
MpegEncContext
*
s
)
{
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
};
// 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
;
double
step
;
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
];
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
]
++
;
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
)
{
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
);
if
(
!
qscale
||
!
blurred_qscale
)
{
av_free
(
qscale
);
av_free
(
blurred_qscale
);
return
AVERROR
(
ENOMEM
);
}
toobig
=
0
;
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
;
/* 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
);
rcc
->
last_qscale_for
[
rce
->
pict_type
]
=
qscale
[
i
];
}
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
];
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
;
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
;
}
blurred_qscale
[
i
]
=
q
/
sum
;
}
/* find expected bits */
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
;
}
ff_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
;
++
toobig
;
}
}
av_free
(
qscale
);
av_free
(
blurred_qscale
);
/* check bitrate calculations and print info */
qscale_sum
=
0
.
0
;
for
(
i
=
0
;
i
<
rcc
->
num_entries
;
i
++
)
{
ff_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
);
}
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
)));
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"[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
"
);
}
else
if
(
toobig
==
40
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"[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
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"[lavc rc] Error: 2pass curve failed to converge
\n
"
);
return
-
1
;
}
return
0
;
}
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