Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
aom-rav1e
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Xiph.Org
aom-rav1e
Commits
0a103ae9
Commit
0a103ae9
authored
Jun 25, 2014
by
Minghai Shang
Committed by
Gerrit Code Review
Jun 25, 2014
Browse files
Options
Browse Files
Download
Plain Diff
Merge "[spatial svc]Implement lag in frames for spatial svc"
parents
35bd31cd
277338f7
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
508 additions
and
349 deletions
+508
-349
examples/vp9_spatial_svc_encoder.c
examples/vp9_spatial_svc_encoder.c
+3
-3
test/svc_test.cc
test/svc_test.cc
+88
-33
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_encoder.c
+84
-11
vp9/encoder/vp9_encoder.h
vp9/encoder/vp9_encoder.h
+4
-0
vp9/encoder/vp9_lookahead.c
vp9/encoder/vp9_lookahead.c
+0
-12
vp9/encoder/vp9_lookahead.h
vp9/encoder/vp9_lookahead.h
+18
-1
vp9/encoder/vp9_svc_layercontext.c
vp9/encoder/vp9_svc_layercontext.c
+99
-0
vp9/encoder/vp9_svc_layercontext.h
vp9/encoder/vp9_svc_layercontext.h
+18
-0
vp9/vp9_cx_iface.c
vp9/vp9_cx_iface.c
+29
-61
vpx/src/svc_encodeframe.c
vpx/src/svc_encodeframe.c
+160
-225
vpx/svc_context.h
vpx/svc_context.h
+5
-3
No files found.
examples/vp9_spatial_svc_encoder.c
View file @
0a103ae9
...
...
@@ -296,6 +296,7 @@ int main(int argc, const char **argv) {
int
frame_duration
=
1
;
/* 1 timebase tick per frame */
FILE
*
infile
=
NULL
;
int
end_of_stream
=
0
;
int
frame_size
;
memset
(
&
svc_ctx
,
0
,
sizeof
(
svc_ctx
));
svc_ctx
.
log_print
=
1
;
...
...
@@ -351,11 +352,10 @@ int main(int argc, const char **argv) {
die_codec
(
&
codec
,
"Failed to encode frame"
);
}
if
(
!
(
app_input
.
passes
==
2
&&
app_input
.
pass
==
1
))
{
if
(
vpx_svc_get_frame_size
(
&
svc_ctx
)
>
0
)
{
while
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_ctx
)
)
>
0
)
{
vpx_video_writer_write_frame
(
writer
,
vpx_svc_get_buffer
(
&
svc_ctx
),
vpx_svc_get_frame_size
(
&
svc_ctx
),
pts
);
frame_size
,
pts
);
}
}
if
(
vpx_svc_get_rc_stats_buffer_size
(
&
svc_ctx
)
>
0
)
{
...
...
test/svc_test.cc
View file @
0a103ae9
...
...
@@ -265,9 +265,17 @@ TEST_F(SvcTest, FirstFrameHasLayers) {
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
EXPECT_EQ
(
VPX_CODEC_OK
,
res
);
if
(
vpx_svc_get_frame_size
(
&
svc_
)
==
0
)
{
// Flush encoder
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
NULL
,
0
,
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
EXPECT_EQ
(
VPX_CODEC_OK
,
res
);
}
int
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
);
EXPECT_GT
(
frame_size
,
0
);
const
vpx_codec_err_t
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
// this test fails with a decoder error
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
...
...
@@ -277,6 +285,9 @@ TEST_F(SvcTest, EncodeThreeFrames) {
svc_
.
spatial_layers
=
2
;
vpx_svc_set_scale_factors
(
&
svc_
,
"4/16,16/16"
);
vpx_svc_set_quantizers
(
&
svc_
,
"40,30"
,
0
);
int
decoded_frames
=
0
;
vpx_codec_err_t
res_dec
;
int
frame_size
;
vpx_codec_err_t
res
=
vpx_svc_init
(
&
svc_
,
&
codec_
,
vpx_codec_vp9_cx
(),
&
codec_enc_
);
...
...
@@ -291,13 +302,14 @@ TEST_F(SvcTest, EncodeThreeFrames) {
// This frame is a keyframe.
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
video
.
img
(),
video
.
pts
(),
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res
);
EXPECT_EQ
(
1
,
vpx_svc_is_keyframe
(
&
svc_
));
vpx_codec_err_t
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
if
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
// FRAME 1
video
.
Next
();
...
...
@@ -305,12 +317,14 @@ TEST_F(SvcTest, EncodeThreeFrames) {
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
video
.
img
(),
video
.
pts
(),
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res
);
EXPECT_EQ
(
0
,
vpx_svc_is_keyframe
(
&
svc_
));
if
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
// FRAME 2
video
.
Next
();
...
...
@@ -318,12 +332,29 @@ TEST_F(SvcTest, EncodeThreeFrames) {
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
video
.
img
(),
video
.
pts
(),
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res
);
EXPECT_EQ
(
0
,
vpx_svc_is_keyframe
(
&
svc_
));
if
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
// Flush encoder
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
NULL
,
0
,
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
EXPECT_EQ
(
VPX_CODEC_OK
,
res
);
while
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
EXPECT_EQ
(
decoded_frames
,
3
);
}
TEST_F
(
SvcTest
,
GetLayerResolution
)
{
...
...
@@ -413,6 +444,9 @@ TEST_F(SvcTest, TwoPassEncode) {
vpx_codec_destroy
(
&
codec_
);
// Second pass encode
int
decoded_frames
=
0
;
vpx_codec_err_t
res_dec
;
int
frame_size
;
codec_enc_
.
g_pass
=
VPX_RC_LAST_PASS
;
codec_enc_
.
rc_twopass_stats_in
.
buf
=
&
stats_buf
[
0
];
codec_enc_
.
rc_twopass_stats_in
.
sz
=
stats_buf
.
size
();
...
...
@@ -427,12 +461,14 @@ TEST_F(SvcTest, TwoPassEncode) {
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
video
.
img
(),
video
.
pts
(),
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res
);
EXPECT_EQ
(
1
,
vpx_svc_is_keyframe
(
&
svc_
));
vpx_codec_err_t
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
if
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
// FRAME 1
video
.
Next
();
...
...
@@ -440,12 +476,14 @@ TEST_F(SvcTest, TwoPassEncode) {
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
video
.
img
(),
video
.
pts
(),
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res
);
EXPECT_EQ
(
0
,
vpx_svc_is_keyframe
(
&
svc_
));
if
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
// FRAME 2
video
.
Next
();
...
...
@@ -453,12 +491,29 @@ TEST_F(SvcTest, TwoPassEncode) {
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
video
.
img
(),
video
.
pts
(),
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res
);
EXPECT_EQ
(
0
,
vpx_svc_is_keyframe
(
&
svc_
));
if
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
// Flush encoder
res
=
vpx_svc_encode
(
&
svc_
,
&
codec_
,
NULL
,
0
,
video
.
duration
(),
VPX_DL_GOOD_QUALITY
);
EXPECT_EQ
(
VPX_CODEC_OK
,
res
);
while
((
frame_size
=
vpx_svc_get_frame_size
(
&
svc_
))
>
0
)
{
EXPECT_EQ
((
decoded_frames
==
0
),
vpx_svc_is_keyframe
(
&
svc_
));
res_dec
=
decoder_
->
DecodeFrame
(
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
vpx_svc_get_frame_size
(
&
svc_
));
static_cast
<
const
uint8_t
*>
(
vpx_svc_get_buffer
(
&
svc_
)),
frame_size
);
ASSERT_EQ
(
VPX_CODEC_OK
,
res_dec
)
<<
decoder_
->
DecodeError
();
++
decoded_frames
;
}
EXPECT_EQ
(
decoded_frames
,
3
);
}
}
// namespace
vp9/encoder/vp9_encoder.c
View file @
0a103ae9
...
...
@@ -106,7 +106,7 @@ static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) {
}
}
static
void
set_high_precision_mv
(
VP9_COMP
*
cpi
,
int
allow_high_precision_mv
)
{
void
vp9_
set_high_precision_mv
(
VP9_COMP
*
cpi
,
int
allow_high_precision_mv
)
{
MACROBLOCK
*
const
mb
=
&
cpi
->
mb
;
cpi
->
common
.
allow_high_precision_mv
=
allow_high_precision_mv
;
if
(
cpi
->
common
.
allow_high_precision_mv
)
{
...
...
@@ -572,7 +572,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
cm
->
reset_frame_context
=
0
;
vp9_reset_segment_features
(
&
cm
->
seg
);
set_high_precision_mv
(
cpi
,
0
);
vp9_
set_high_precision_mv
(
cpi
,
0
);
{
int
i
;
...
...
@@ -2117,7 +2117,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if
(
!
frame_is_intra_only
(
cm
))
{
cm
->
interp_filter
=
DEFAULT_INTERP_FILTER
;
/* TODO: Decide this more intelligently */
set_high_precision_mv
(
cpi
,
q
<
HIGH_PRECISION_MV_QTHRESH
);
vp9_
set_high_precision_mv
(
cpi
,
q
<
HIGH_PRECISION_MV_QTHRESH
);
}
if
(
cpi
->
sf
.
recode_loop
==
DISALLOW_RECODE
)
{
...
...
@@ -2298,12 +2298,22 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags,
int
res
=
0
;
const
int
subsampling_x
=
sd
->
uv_width
<
sd
->
y_width
;
const
int
subsampling_y
=
sd
->
uv_height
<
sd
->
y_height
;
const
int
is_spatial_svc
=
cpi
->
use_svc
&&
(
cpi
->
svc
.
number_temporal_layers
==
1
);
check_initial_width
(
cpi
,
subsampling_x
,
subsampling_y
);
vpx_usec_timer_start
(
&
timer
);
if
(
vp9_lookahead_push
(
cpi
->
lookahead
,
sd
,
time_stamp
,
end_time
,
frame_flags
))
#ifdef CONFIG_SPATIAL_SVC
if
(
is_spatial_svc
)
res
=
vp9_svc_lookahead_push
(
cpi
,
cpi
->
lookahead
,
sd
,
time_stamp
,
end_time
,
frame_flags
);
else
#endif
res
=
vp9_lookahead_push
(
cpi
->
lookahead
,
sd
,
time_stamp
,
end_time
,
frame_flags
);
if
(
res
)
res
=
-
1
;
vpx_usec_timer_mark
(
&
timer
);
cpi
->
time_receive_data
+=
vpx_usec_timer_elapsed
(
&
timer
);
...
...
@@ -2419,11 +2429,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
YV12_BUFFER_CONFIG
*
force_src_buffer
=
NULL
;
MV_REFERENCE_FRAME
ref_frame
;
int
arf_src_index
;
const
int
is_spatial_svc
=
cpi
->
use_svc
&&
(
cpi
->
svc
.
number_temporal_layers
==
1
);
if
(
!
cpi
)
return
-
1
;
if
(
cpi
->
svc
.
number_spatial_layers
>
1
&&
cpi
->
pass
==
2
)
{
if
(
is_spatial_svc
&&
cpi
->
pass
==
2
)
{
vp9_svc_lookahead_peek
(
cpi
,
cpi
->
lookahead
,
0
,
1
);
vp9_restore_layer_context
(
cpi
);
}
...
...
@@ -2432,7 +2445,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
cpi
->
source
=
NULL
;
cpi
->
last_source
=
NULL
;
set_high_precision_mv
(
cpi
,
ALTREF_HIGH_PRECISION_MV
);
vp9_
set_high_precision_mv
(
cpi
,
ALTREF_HIGH_PRECISION_MV
);
// Normal defaults
cm
->
reset_frame_context
=
0
;
...
...
@@ -2446,7 +2459,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if
(
arf_src_index
)
{
assert
(
arf_src_index
<=
rc
->
frames_to_key
);
if
((
cpi
->
source
=
vp9_lookahead_peek
(
cpi
->
lookahead
,
arf_src_index
)))
{
#ifdef CONFIG_SPATIAL_SVC
if
(
is_spatial_svc
)
cpi
->
source
=
vp9_svc_lookahead_peek
(
cpi
,
cpi
->
lookahead
,
arf_src_index
,
1
);
else
#endif
cpi
->
source
=
vp9_lookahead_peek
(
cpi
->
lookahead
,
arf_src_index
);
if
(
cpi
->
source
!=
NULL
)
{
cpi
->
alt_ref_source
=
cpi
->
source
;
if
(
cpi
->
oxcf
.
arnr_max_frames
>
0
)
{
...
...
@@ -2472,12 +2492,24 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if
(
!
cpi
->
source
)
{
// Get last frame source.
if
(
cm
->
current_video_frame
>
0
)
{
if
((
cpi
->
last_source
=
vp9_lookahead_peek
(
cpi
->
lookahead
,
-
1
))
==
NULL
)
#ifdef CONFIG_SPATIAL_SVC
if
(
is_spatial_svc
)
cpi
->
last_source
=
vp9_svc_lookahead_peek
(
cpi
,
cpi
->
lookahead
,
-
1
,
0
);
else
#endif
cpi
->
last_source
=
vp9_lookahead_peek
(
cpi
->
lookahead
,
-
1
);
if
(
cpi
->
last_source
==
NULL
)
return
-
1
;
}
// Read in the source frame.
if
((
cpi
->
source
=
vp9_lookahead_pop
(
cpi
->
lookahead
,
flush
)))
{
#ifdef CONFIG_SPATIAL_SVC
if
(
is_spatial_svc
)
cpi
->
source
=
vp9_svc_lookahead_pop
(
cpi
,
cpi
->
lookahead
,
flush
);
else
#endif
cpi
->
source
=
vp9_lookahead_pop
(
cpi
->
lookahead
,
flush
);
if
(
cpi
->
source
!=
NULL
)
{
cm
->
show_frame
=
1
;
cm
->
intra_only
=
0
;
...
...
@@ -2499,7 +2531,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
*
time_stamp
=
cpi
->
source
->
ts_start
;
*
time_end
=
cpi
->
source
->
ts_end
;
*
frame_flags
=
cpi
->
source
->
flags
;
*
frame_flags
=
(
cpi
->
source
->
flags
&
VPX_EFLAG_FORCE_KF
)
?
FRAMEFLAGS_KEY
:
0
;
}
else
{
*
size
=
0
;
if
(
flush
&&
cpi
->
pass
==
1
&&
!
cpi
->
twopass
.
first_pass_done
)
{
...
...
@@ -2830,3 +2864,42 @@ int vp9_get_y_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b) {
int
vp9_get_quantizer
(
VP9_COMP
*
cpi
)
{
return
cpi
->
common
.
base_qindex
;
}
void
vp9_apply_encoding_flags
(
VP9_COMP
*
cpi
,
vpx_enc_frame_flags_t
flags
)
{
if
(
flags
&
(
VP8_EFLAG_NO_REF_LAST
|
VP8_EFLAG_NO_REF_GF
|
VP8_EFLAG_NO_REF_ARF
))
{
int
ref
=
7
;
if
(
flags
&
VP8_EFLAG_NO_REF_LAST
)
ref
^=
VP9_LAST_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_REF_GF
)
ref
^=
VP9_GOLD_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_REF_ARF
)
ref
^=
VP9_ALT_FLAG
;
vp9_use_as_reference
(
cpi
,
ref
);
}
if
(
flags
&
(
VP8_EFLAG_NO_UPD_LAST
|
VP8_EFLAG_NO_UPD_GF
|
VP8_EFLAG_NO_UPD_ARF
|
VP8_EFLAG_FORCE_GF
|
VP8_EFLAG_FORCE_ARF
))
{
int
upd
=
7
;
if
(
flags
&
VP8_EFLAG_NO_UPD_LAST
)
upd
^=
VP9_LAST_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_UPD_GF
)
upd
^=
VP9_GOLD_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_UPD_ARF
)
upd
^=
VP9_ALT_FLAG
;
vp9_update_reference
(
cpi
,
upd
);
}
if
(
flags
&
VP8_EFLAG_NO_UPD_ENTROPY
)
{
vp9_update_entropy
(
cpi
,
0
);
}
}
vp9/encoder/vp9_encoder.h
View file @
0a103ae9
...
...
@@ -517,10 +517,14 @@ void vp9_update_reference_frames(VP9_COMP *cpi);
int64_t
vp9_rescale
(
int64_t
val
,
int64_t
num
,
int
denom
);
void
vp9_set_high_precision_mv
(
VP9_COMP
*
cpi
,
int
allow_high_precision_mv
);
YV12_BUFFER_CONFIG
*
vp9_scale_if_required
(
VP9_COMMON
*
cm
,
YV12_BUFFER_CONFIG
*
unscaled
,
YV12_BUFFER_CONFIG
*
scaled
);
void
vp9_apply_encoding_flags
(
VP9_COMP
*
cpi
,
vpx_enc_frame_flags_t
flags
);
static
INLINE
void
set_ref_ptrs
(
VP9_COMMON
*
cm
,
MACROBLOCKD
*
xd
,
MV_REFERENCE_FRAME
ref0
,
MV_REFERENCE_FRAME
ref1
)
{
...
...
vp9/encoder/vp9_lookahead.c
View file @
0a103ae9
...
...
@@ -18,18 +18,6 @@
#include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_lookahead.h"
// The max of past frames we want to keep in the queue.
#define MAX_PRE_FRAMES 1
struct
lookahead_ctx
{
unsigned
int
max_sz
;
/* Absolute size of the queue */
unsigned
int
sz
;
/* Number of buffers currently in the queue */
unsigned
int
read_idx
;
/* Read index */
unsigned
int
write_idx
;
/* Write index */
struct
lookahead_entry
*
buf
;
/* Buffer list */
};
/* Return the buffer at the given absolute index and increment the index */
static
struct
lookahead_entry
*
pop
(
struct
lookahead_ctx
*
ctx
,
unsigned
int
*
idx
)
{
...
...
vp9/encoder/vp9_lookahead.h
View file @
0a103ae9
...
...
@@ -14,6 +14,11 @@
#include "vpx_scale/yv12config.h"
#include "vpx/vpx_integer.h"
#ifdef CONFIG_SPATIAL_SVC
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#endif
#ifdef __cplusplus
extern
"C"
{
#endif
...
...
@@ -25,10 +30,22 @@ struct lookahead_entry {
int64_t
ts_start
;
int64_t
ts_end
;
unsigned
int
flags
;
#ifdef CONFIG_SPATIAL_SVC
vpx_svc_parameters_t
svc_params
[
VPX_SS_MAX_LAYERS
];
#endif
};
// The max of past frames we want to keep in the queue.
#define MAX_PRE_FRAMES 1
struct
lookahead_ctx
;
struct
lookahead_ctx
{
unsigned
int
max_sz
;
/* Absolute size of the queue */
unsigned
int
sz
;
/* Number of buffers currently in the queue */
unsigned
int
read_idx
;
/* Read index */
unsigned
int
write_idx
;
/* Write index */
struct
lookahead_entry
*
buf
;
/* Buffer list */
};
/**\brief Initializes the lookahead stage
*
...
...
vp9/encoder/vp9_svc_layercontext.c
View file @
0a103ae9
...
...
@@ -12,6 +12,7 @@
#include "vp9/encoder/vp9_encoder.h"
#include "vp9/encoder/vp9_svc_layercontext.h"
#include "vp9/encoder/vp9_extend.h"
void
vp9_init_layer_context
(
VP9_COMP
*
const
cpi
)
{
SVC
*
const
svc
=
&
cpi
->
svc
;
...
...
@@ -209,3 +210,101 @@ int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
cpi
->
svc
.
spatial_layer_id
>
0
&&
cpi
->
svc
.
layer_context
[
cpi
->
svc
.
spatial_layer_id
].
is_key_frame
;
}
int
vp9_svc_lookahead_push
(
const
VP9_COMP
*
const
cpi
,
struct
lookahead_ctx
*
ctx
,
YV12_BUFFER_CONFIG
*
src
,
int64_t
ts_start
,
int64_t
ts_end
,
unsigned
int
flags
)
{
struct
lookahead_entry
*
buf
;
int
i
,
index
;
if
(
vp9_lookahead_push
(
ctx
,
src
,
ts_start
,
ts_end
,
flags
))
return
1
;
index
=
ctx
->
write_idx
-
1
;
if
(
index
<
0
)
index
+=
ctx
->
max_sz
;
buf
=
ctx
->
buf
+
index
;
if
(
buf
==
NULL
)
return
1
;
// Store svc parameters for each layer
for
(
i
=
0
;
i
<
cpi
->
svc
.
number_spatial_layers
;
++
i
)
buf
->
svc_params
[
i
]
=
cpi
->
svc
.
layer_context
[
i
].
svc_params_received
;
return
0
;
}
static
int
copy_svc_params
(
VP9_COMP
*
const
cpi
,
struct
lookahead_entry
*
buf
)
{
int
layer_id
;
vpx_svc_parameters_t
*
layer_param
;
vpx_enc_frame_flags_t
flags
;
// Find the next layer to be encoded
for
(
layer_id
=
0
;
layer_id
<
cpi
->
svc
.
number_spatial_layers
;
++
layer_id
)
{
if
(
buf
->
svc_params
[
layer_id
].
spatial_layer
>=
0
)
break
;
}
if
(
layer_id
==
cpi
->
svc
.
number_spatial_layers
)
return
1
;
layer_param
=
&
buf
->
svc_params
[
layer_id
];
buf
->
flags
=
flags
=
layer_param
->
flags
;
cpi
->
svc
.
spatial_layer_id
=
layer_param
->
spatial_layer
;
cpi
->
svc
.
temporal_layer_id
=
layer_param
->
temporal_layer
;
cpi
->
lst_fb_idx
=
layer_param
->
lst_fb_idx
;
cpi
->
gld_fb_idx
=
layer_param
->
gld_fb_idx
;
cpi
->
alt_fb_idx
=
layer_param
->
alt_fb_idx
;
if
(
vp9_set_size_literal
(
cpi
,
layer_param
->
width
,
layer_param
->
height
)
!=
0
)
return
VPX_CODEC_INVALID_PARAM
;
cpi
->
oxcf
.
worst_allowed_q
=
vp9_quantizer_to_qindex
(
layer_param
->
max_quantizer
);
cpi
->
oxcf
.
best_allowed_q
=
vp9_quantizer_to_qindex
(
layer_param
->
min_quantizer
);
vp9_change_config
(
cpi
,
&
cpi
->
oxcf
);
vp9_set_high_precision_mv
(
cpi
,
1
);
// Retrieve the encoding flags for each layer and apply it to encoder.
// It includes reference frame flags and update frame flags.
vp9_apply_encoding_flags
(
cpi
,
flags
);
return
0
;
}
struct
lookahead_entry
*
vp9_svc_lookahead_peek
(
VP9_COMP
*
const
cpi
,
struct
lookahead_ctx
*
ctx
,
int
index
,
int
copy_params
)
{
struct
lookahead_entry
*
buf
=
vp9_lookahead_peek
(
ctx
,
index
);
if
(
buf
!=
NULL
&&
copy_params
!=
0
)
{
if
(
copy_svc_params
(
cpi
,
buf
)
!=
0
)
return
NULL
;
}
return
buf
;
}
struct
lookahead_entry
*
vp9_svc_lookahead_pop
(
VP9_COMP
*
const
cpi
,
struct
lookahead_ctx
*
ctx
,
int
drain
)
{
struct
lookahead_entry
*
buf
=
NULL
;
if
(
ctx
->
sz
&&
(
drain
||
ctx
->
sz
==
ctx
->
max_sz
-
MAX_PRE_FRAMES
))
{
buf
=
vp9_svc_lookahead_peek
(
cpi
,
ctx
,
0
,
1
);
if
(
buf
!=
NULL
)
{
// Only remove the buffer when pop the highest layer. Simply set the
// spatial_layer to -1 for lower layers.
buf
->
svc_params
[
cpi
->
svc
.
spatial_layer_id
].
spatial_layer
=
-
1
;
if
(
cpi
->
svc
.
spatial_layer_id
==
cpi
->
svc
.
number_spatial_layers
-
1
)
{
vp9_lookahead_pop
(
ctx
,
drain
);
}
}
}
return
buf
;
}
vp9/encoder/vp9_svc_layercontext.h
View file @
0a103ae9
...
...
@@ -28,6 +28,7 @@ typedef struct {
struct
vpx_fixed_buf
rc_twopass_stats_in
;
unsigned
int
current_video_frame_in_layer
;
int
is_key_frame
;
vpx_svc_parameters_t
svc_params_received
;
}
LAYER_CONTEXT
;
typedef
struct
{
...
...
@@ -74,6 +75,23 @@ void vp9_inc_frame_in_layer(SVC *svc);
// Check if current layer is key frame in spatial upper layer
int
vp9_is_upper_layer_key_frame
(
const
struct
VP9_COMP
*
const
cpi
);
// Copy the source image, flags and svc parameters into a new framebuffer
// with the expected stride/border
int
vp9_svc_lookahead_push
(
const
struct
VP9_COMP
*
const
cpi
,
struct
lookahead_ctx
*
ctx
,
YV12_BUFFER_CONFIG
*
src
,
int64_t
ts_start
,
int64_t
ts_end
,
unsigned
int
flags
);
// Get the next source buffer to encode
struct
lookahead_entry
*
vp9_svc_lookahead_pop
(
struct
VP9_COMP
*
const
cpi
,
struct
lookahead_ctx
*
ctx
,
int
drain
);
// Get a future source buffer to encode
struct
lookahead_entry
*
vp9_svc_lookahead_peek
(
struct
VP9_COMP
*
const
cpi
,
struct
lookahead_ctx
*
ctx
,
int
index
,
int
copy_params
);
#ifdef __cplusplus
}
// extern "C"
#endif
...
...
vp9/vp9_cx_iface.c
View file @
0a103ae9
...
...
@@ -88,7 +88,7 @@ struct vpx_codec_alg_priv {
size_t
pending_frame_magnitude
;
vpx_image_t
preview_img
;
vp8_postproc_cfg_t
preview_ppcfg
;
vpx_codec_pkt_list_decl
(
64
)
pkt_list
;
vpx_codec_pkt_list_decl
(
128
)
pkt_list
;
unsigned
int
fixed_kf_cntr
;
};
...
...
@@ -795,42 +795,7 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx,
return
VPX_CODEC_INVALID_PARAM
;
}
if
(
flags
&
(
VP8_EFLAG_NO_REF_LAST
|
VP8_EFLAG_NO_REF_GF
|
VP8_EFLAG_NO_REF_ARF
))
{
int
ref
=
7
;
if
(
flags
&
VP8_EFLAG_NO_REF_LAST
)
ref
^=
VP9_LAST_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_REF_GF
)
ref
^=
VP9_GOLD_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_REF_ARF
)
ref
^=
VP9_ALT_FLAG
;
vp9_use_as_reference
(
ctx
->
cpi
,
ref
);
}
if
(
flags
&
(
VP8_EFLAG_NO_UPD_LAST
|
VP8_EFLAG_NO_UPD_GF
|
VP8_EFLAG_NO_UPD_ARF
|
VP8_EFLAG_FORCE_GF
|
VP8_EFLAG_FORCE_ARF
))
{
int
upd
=
7
;
if
(
flags
&
VP8_EFLAG_NO_UPD_LAST
)
upd
^=
VP9_LAST_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_UPD_GF
)
upd
^=
VP9_GOLD_FLAG
;
if
(
flags
&
VP8_EFLAG_NO_UPD_ARF
)
upd
^=
VP9_ALT_FLAG
;
vp9_update_reference
(
ctx
->
cpi
,
upd
);
}
if
(
flags
&
VP8_EFLAG_NO_UPD_ENTROPY
)
{
vp9_update_entropy
(
ctx
->
cpi
,
0
);
}
vp9_apply_encoding_flags
(
ctx
->
cpi
,
flags
);