Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
aom-rav1e
Commits
422cf740
Commit
422cf740
authored
Oct 16, 2014
by
Paul Wilkins
Committed by
Gerrit Code Review
Oct 16, 2014
Browse files
Merge "[spatial svc]Another workaround to avoid using prev_mi"
parents
9f47c52d
68b550f5
Changes
9
Hide whitespace changes
Inline
Side-by-side
test/svc_test.cc
View file @
422cf740
...
...
@@ -225,10 +225,9 @@ class SvcTest : public ::testing::Test {
EXPECT_EQ
(
received_frames
,
n
);
}
void
DropLayersAndMakeItVP9Comaptible
(
struct
vpx_fixed_buf
*
const
inputs
,
const
int
num_super_frames
,
const
int
remained_spatial_layers
,
const
bool
is_multiple_frame_contexts
)
{
void
DropEnhancementLayers
(
struct
vpx_fixed_buf
*
const
inputs
,
const
int
num_super_frames
,
const
int
remained_spatial_layers
)
{
ASSERT_TRUE
(
inputs
!=
NULL
);
ASSERT_GT
(
num_super_frames
,
0
);
ASSERT_GT
(
remained_spatial_layers
,
0
);
...
...
@@ -250,45 +249,6 @@ class SvcTest : public ::testing::Test {
if
(
frame_count
==
0
)
{
// There's no super frame but only a single frame.
ASSERT_EQ
(
1
,
remained_spatial_layers
);
if
(
is_multiple_frame_contexts
)
{
// Make a new super frame.
uint8_t
marker
=
0xc1
;
unsigned
int
mask
;
int
mag
;
// Choose the magnitude.
for
(
mag
=
0
,
mask
=
0xff
;
mag
<
4
;
++
mag
)
{
if
(
inputs
[
i
].
sz
<
mask
)
break
;
mask
<<=
8
;
mask
|=
0xff
;
}
marker
|=
mag
<<
3
;
int
index_sz
=
2
+
(
mag
+
1
)
*
2
;
inputs
[
i
].
buf
=
realloc
(
inputs
[
i
].
buf
,
inputs
[
i
].
sz
+
index_sz
+
16
);
ASSERT_TRUE
(
inputs
[
i
].
buf
!=
NULL
);
uint8_t
*
frame_data
=
static_cast
<
uint8_t
*>
(
inputs
[
i
].
buf
);
frame_data
[
0
]
&=
~
2
;
// Set the show_frame flag to 0.
frame_data
+=
inputs
[
i
].
sz
;
// Add an one byte frame with show_existing_frame.
*
frame_data
++
=
0x88
;
// Write the super frame index.
*
frame_data
++
=
marker
;
frame_sizes
[
0
]
=
inputs
[
i
].
sz
;
frame_sizes
[
1
]
=
1
;
for
(
int
j
=
0
;
j
<
2
;
++
j
)
{
unsigned
int
this_sz
=
frame_sizes
[
j
];
for
(
int
k
=
0
;
k
<=
mag
;
k
++
)
{
*
frame_data
++
=
this_sz
&
0xff
;
this_sz
>>=
8
;
}
}
*
frame_data
++
=
marker
;
inputs
[
i
].
sz
+=
index_sz
+
1
;
}
}
else
{
// Found a super frame.
uint8_t
*
frame_data
=
static_cast
<
uint8_t
*>
(
inputs
[
i
].
buf
);
...
...
@@ -304,16 +264,13 @@ class SvcTest : public ::testing::Test {
}
ASSERT_LT
(
frame
,
frame_count
)
<<
"Couldn't find a visible frame. "
<<
"remained_spatial_layers: "
<<
remained_spatial_layers
<<
" super_frame: "
<<
i
<<
" is_multiple_frame_context: "
<<
is_multiple_frame_contexts
;
if
(
frame
==
frame_count
-
1
&&
!
is_multiple_frame_contexts
)
<<
" super_frame: "
<<
i
;
if
(
frame
==
frame_count
-
1
)
continue
;
frame_data
+=
frame_sizes
[
frame
];
// We need to add one more frame for multiple frame contexts.
if
(
is_multiple_frame_contexts
)
++
frame
;
uint8_t
marker
=
static_cast
<
const
uint8_t
*>
(
inputs
[
i
].
buf
)[
inputs
[
i
].
sz
-
1
];
const
uint32_t
mag
=
((
marker
>>
3
)
&
0x3
)
+
1
;
...
...
@@ -323,35 +280,14 @@ class SvcTest : public ::testing::Test {
marker
|=
frame
;
// Copy existing frame sizes.
memmove
(
frame_data
+
(
is_multiple_frame_contexts
?
2
:
1
),
frame_start
+
inputs
[
i
].
sz
-
index_sz
+
1
,
new_index_sz
-
2
);
if
(
is_multiple_frame_contexts
)
{
// Add a one byte frame with flag show_existing_frame.
*
frame_data
++
=
0x88
|
(
remained_spatial_layers
-
1
);
}
memmove
(
frame_data
+
1
,
frame_start
+
inputs
[
i
].
sz
-
index_sz
+
1
,
new_index_sz
-
2
);
// New marker.
frame_data
[
0
]
=
marker
;
frame_data
+=
(
mag
*
(
frame
+
1
)
+
1
);
if
(
is_multiple_frame_contexts
)
{
// Write the frame size for the one byte frame.
frame_data
-=
mag
;
*
frame_data
++
=
1
;
for
(
uint32_t
j
=
1
;
j
<
mag
;
++
j
)
{
*
frame_data
++
=
0
;
}
}
*
frame_data
++
=
marker
;
inputs
[
i
].
sz
=
frame_data
-
frame_start
;
if
(
is_multiple_frame_contexts
)
{
// Change the show frame flag to 0 for all frames.
for
(
int
j
=
0
;
j
<
frame
;
++
j
)
{
frame_start
[
0
]
&=
~
2
;
frame_start
+=
frame_sizes
[
j
];
}
}
}
}
}
...
...
@@ -555,7 +491,7 @@ TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
vpx_fixed_buf
outputs
[
10
];
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
2
,
&
outputs
[
0
]);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
1
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
10
,
1
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
}
...
...
@@ -573,13 +509,13 @@ TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
5
,
&
outputs
[
0
]);
DecodeNFrames
(
&
outputs
[
0
],
10
);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
4
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
10
,
4
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
3
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
10
,
3
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
2
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
10
,
2
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
1
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
10
,
1
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
...
...
@@ -616,9 +552,9 @@ TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
20
,
3
,
&
outputs
[
0
]);
DecodeNFrames
(
&
outputs
[
0
],
20
);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
20
,
2
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
20
,
2
);
DecodeNFrames
(
&
outputs
[
0
],
20
);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
20
,
1
,
false
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
20
,
1
);
DecodeNFrames
(
&
outputs
[
0
],
20
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
20
);
...
...
@@ -649,7 +585,6 @@ TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
vpx_fixed_buf
outputs
[
10
];
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
2
,
&
outputs
[
0
]);
DropLayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
2
,
true
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
}
...
...
@@ -667,7 +602,7 @@ TEST_F(SvcTest,
vpx_fixed_buf
outputs
[
10
];
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
2
,
&
outputs
[
0
]);
Drop
LayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
1
,
true
);
Drop
EnhancementLayers
(
&
outputs
[
0
],
10
,
1
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
}
...
...
@@ -686,7 +621,6 @@ TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
vpx_fixed_buf
outputs
[
10
];
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
2
,
&
outputs
[
0
]);
DropLayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
2
,
true
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
}
...
...
@@ -707,32 +641,13 @@ TEST_F(SvcTest,
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
3
,
&
outputs
[
0
]);
vpx_fixed_buf
outputs_new
[
10
];
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
outputs_new
[
i
].
buf
=
malloc
(
outputs
[
i
].
sz
+
16
);
ASSERT_TRUE
(
outputs_new
[
i
].
buf
!=
NULL
);
memcpy
(
outputs_new
[
i
].
buf
,
outputs
[
i
].
buf
,
outputs
[
i
].
sz
);
outputs_new
[
i
].
sz
=
outputs
[
i
].
sz
;
}
DropLayersAndMakeItVP9Comaptible
(
&
outputs_new
[
0
],
10
,
3
,
true
);
DecodeNFrames
(
&
outputs_new
[
0
],
10
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
memcpy
(
outputs_new
[
i
].
buf
,
outputs
[
i
].
buf
,
outputs
[
i
].
sz
);
outputs_new
[
i
].
sz
=
outputs
[
i
].
sz
;
}
DropLayersAndMakeItVP9Comaptible
(
&
outputs_new
[
0
],
10
,
2
,
true
);
DecodeNFrames
(
&
outputs_new
[
0
],
10
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
memcpy
(
outputs_new
[
i
].
buf
,
outputs
[
i
].
buf
,
outputs
[
i
].
sz
);
outputs_new
[
i
].
sz
=
outputs
[
i
].
sz
;
}
DropLayersAndMakeItVP9Comaptible
(
&
outputs_new
[
0
],
10
,
1
,
true
);
DecodeNFrames
(
&
outputs_new
[
0
],
10
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
DropEnhancementLayers
(
&
outputs
[
0
],
10
,
2
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
DropEnhancementLayers
(
&
outputs
[
0
],
10
,
1
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs_new
[
0
],
10
);
}
TEST_F
(
SvcTest
,
TwoPassEncode2TemporalLayers
)
{
...
...
@@ -769,7 +684,6 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
vpx_fixed_buf
outputs
[
10
];
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
1
,
&
outputs
[
0
]);
DropLayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
1
,
true
);
DecodeNFrames
(
&
outputs
[
0
],
10
);
FreeBitstreamBuffers
(
&
outputs
[
0
],
10
);
}
...
...
@@ -814,7 +728,6 @@ TEST_F(SvcTest,
vpx_fixed_buf
outputs
[
10
];
memset
(
&
outputs
[
0
],
0
,
sizeof
(
outputs
));
Pass2EncodeNFrames
(
&
stats_buf
,
10
,
1
,
&
outputs
[
0
]);
DropLayersAndMakeItVP9Comaptible
(
&
outputs
[
0
],
10
,
1
,
true
);
vpx_fixed_buf
base_layer
[
5
];
for
(
int
i
=
0
;
i
<
5
;
++
i
)
...
...
vp9/encoder/vp9_bitstream.c
View file @
422cf740
...
...
@@ -1013,7 +1013,11 @@ static void write_frame_size_with_refs(VP9_COMP *cpi,
((
cpi
->
svc
.
number_temporal_layers
>
1
&&
cpi
->
oxcf
.
rc_mode
==
VPX_CBR
)
||
(
cpi
->
svc
.
number_spatial_layers
>
1
&&
cpi
->
svc
.
layer_context
[
cpi
->
svc
.
spatial_layer_id
].
is_key_frame
)))
{
cpi
->
svc
.
layer_context
[
cpi
->
svc
.
spatial_layer_id
].
is_key_frame
)
||
(
is_two_pass_svc
(
cpi
)
&&
cpi
->
svc
.
encode_empty_frame_state
==
ENCODING
&&
cpi
->
svc
.
layer_context
[
0
].
frames_from_key_frame
<
cpi
->
svc
.
number_temporal_layers
+
1
)))
{
found
=
0
;
}
vp9_wb_write_bit
(
wb
,
found
);
...
...
@@ -1105,8 +1109,7 @@ static void write_uncompressed_header(VP9_COMP *cpi,
// will change to show_frame flag to 0, then add an one byte frame with
// show_existing_frame flag which tells the decoder which frame we want to
// show.
if
(
!
cm
->
show_frame
||
(
is_two_pass_svc
(
cpi
)
&&
cm
->
error_resilient_mode
==
0
))
if
(
!
cm
->
show_frame
)
vp9_wb_write_bit
(
wb
,
cm
->
intra_only
);
if
(
!
cm
->
error_resilient_mode
)
...
...
vp9/encoder/vp9_encoder.c
View file @
422cf740
...
...
@@ -225,6 +225,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
}
vpx_memset
(
&
cpi
->
svc
.
scaled_frames
[
0
],
0
,
MAX_LAG_BUFFERS
*
sizeof
(
cpi
->
svc
.
scaled_frames
[
0
]));
vp9_free_frame_buffer
(
&
cpi
->
svc
.
empty_frame
.
img
);
vpx_memset
(
&
cpi
->
svc
.
empty_frame
,
0
,
sizeof
(
cpi
->
svc
.
empty_frame
));
}
static
void
save_coding_context
(
VP9_COMP
*
cpi
)
{
...
...
@@ -2979,7 +2982,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
}
if
(
is_two_pass_svc
(
cpi
)
&&
cm
->
error_resilient_mode
==
0
)
{
// Use the last frame context for the empty frame.
cm
->
frame_context_idx
=
(
cpi
->
svc
.
encode_empty_frame_state
==
ENCODING
)
?
FRAME_CONTEXTS
-
1
:
cpi
->
svc
.
spatial_layer_id
*
cpi
->
svc
.
number_temporal_layers
+
cpi
->
svc
.
temporal_layer_id
;
...
...
@@ -3160,7 +3165,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cpi
->
ref_frame_flags
=
get_ref_frame_flags
(
cpi
);
cm
->
last_frame_type
=
cm
->
frame_type
;
vp9_rc_postencode_update
(
cpi
,
*
size
);
if
(
!
(
is_two_pass_svc
(
cpi
)
&&
cpi
->
svc
.
encode_empty_frame_state
==
ENCODING
))
vp9_rc_postencode_update
(
cpi
,
*
size
);
#if 0
output_frame_level_debug_stats(cpi);
...
...
@@ -3184,12 +3191,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm
->
last_height
=
cm
->
height
;
// reset to normal state now that we are done.
if
(
!
cm
->
show_existing_frame
)
{
if
(
is_two_pass_svc
(
cpi
)
&&
cm
->
error_resilient_mode
==
0
)
cm
->
last_show_frame
=
0
;
else
cm
->
last_show_frame
=
cm
->
show_frame
;
}
if
(
!
cm
->
show_existing_frame
)
cm
->
last_show_frame
=
cm
->
show_frame
;
if
(
cm
->
show_frame
)
{
vp9_swap_mi_and_prev_mi
(
cm
);
...
...
@@ -3226,7 +3229,9 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
uint8_t
*
dest
,
unsigned
int
*
frame_flags
)
{
cpi
->
allow_encode_breakout
=
ENCODE_BREAKOUT_ENABLED
;
encode_frame_to_data_rate
(
cpi
,
size
,
dest
,
frame_flags
);
vp9_twopass_postencode_update
(
cpi
);
if
(
!
(
is_two_pass_svc
(
cpi
)
&&
cpi
->
svc
.
encode_empty_frame_state
==
ENCODING
))
vp9_twopass_postencode_update
(
cpi
);
}
static
void
init_motion_estimation
(
VP9_COMP
*
cpi
)
{
...
...
@@ -3414,6 +3419,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if
(
is_two_pass_svc
(
cpi
))
{
#if CONFIG_SPATIAL_SVC
vp9_svc_start_frame
(
cpi
);
// Use a small empty frame instead of a real frame
if
(
cpi
->
svc
.
encode_empty_frame_state
==
ENCODING
)
source
=
&
cpi
->
svc
.
empty_frame
;
#endif
if
(
oxcf
->
pass
==
2
)
vp9_restore_layer_context
(
cpi
);
...
...
@@ -3432,6 +3440,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
// Should we encode an arf frame.
arf_src_index
=
get_arf_src_index
(
cpi
);
// Skip alt frame if we encode the empty frame
if
(
is_two_pass_svc
(
cpi
)
&&
source
!=
NULL
)
arf_src_index
=
0
;
if
(
arf_src_index
)
{
assert
(
arf_src_index
<=
rc
->
frames_to_key
);
...
...
@@ -3542,7 +3555,10 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
// For two pass encodes analyse the first pass stats and determine
// the bit allocation and other parameters for this frame / group of frames.
if
((
oxcf
->
pass
==
2
)
&&
(
!
cpi
->
use_svc
||
is_two_pass_svc
(
cpi
)))
{
if
((
oxcf
->
pass
==
2
)
&&
(
!
cpi
->
use_svc
||
(
is_two_pass_svc
(
cpi
)
&&
cpi
->
svc
.
encode_empty_frame_state
!=
ENCODING
)))
{
vp9_rc_get_second_pass_params
(
cpi
);
}
...
...
@@ -3771,10 +3787,18 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
#endif
if
(
is_two_pass_svc
(
cpi
)
&&
cm
->
show_frame
)
{
++
cpi
->
svc
.
spatial_layer_to_encode
;
if
(
cpi
->
svc
.
spatial_layer_to_encode
>=
cpi
->
svc
.
number_spatial_layers
)
cpi
->
svc
.
spatial_layer_to_encode
=
0
;
if
(
is_two_pass_svc
(
cpi
))
{
if
(
cpi
->
svc
.
encode_empty_frame_state
==
ENCODING
)
cpi
->
svc
.
encode_empty_frame_state
=
ENCODED
;
if
(
cm
->
show_frame
)
{
++
cpi
->
svc
.
spatial_layer_to_encode
;
if
(
cpi
->
svc
.
spatial_layer_to_encode
>=
cpi
->
svc
.
number_spatial_layers
)
cpi
->
svc
.
spatial_layer_to_encode
=
0
;
// May need the empty frame after an visible frame.
cpi
->
svc
.
encode_empty_frame_state
=
NEED_TO_ENCODE
;
}
}
return
0
;
}
...
...
@@ -3865,10 +3889,6 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width,
if
(
width
)
{
cm
->
width
=
width
;
if
(
cm
->
width
*
5
<
cpi
->
initial_width
)
{
cm
->
width
=
cpi
->
initial_width
/
5
+
1
;
printf
(
"Warning: Desired width too small, changed to %d
\n
"
,
cm
->
width
);
}
if
(
cm
->
width
>
cpi
->
initial_width
)
{
cm
->
width
=
cpi
->
initial_width
;
printf
(
"Warning: Desired width too large, changed to %d
\n
"
,
cm
->
width
);
...
...
@@ -3877,10 +3897,6 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width,
if
(
height
)
{
cm
->
height
=
height
;
if
(
cm
->
height
*
5
<
cpi
->
initial_height
)
{
cm
->
height
=
cpi
->
initial_height
/
5
+
1
;
printf
(
"Warning: Desired height too small, changed to %d
\n
"
,
cm
->
height
);
}
if
(
cm
->
height
>
cpi
->
initial_height
)
{
cm
->
height
=
cpi
->
initial_height
;
printf
(
"Warning: Desired height too large, changed to %d
\n
"
,
cm
->
height
);
...
...
vp9/encoder/vp9_firstpass.c
View file @
422cf740
...
...
@@ -2405,6 +2405,9 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
cpi
->
ref_frame_flags
&=
(
~
VP9_LAST_FLAG
&
~
VP9_GOLD_FLAG
&
~
VP9_ALT_FLAG
);
lc
->
frames_from_key_frame
=
0
;
// Reset the empty frame resolution since we have a key frame.
cpi
->
svc
.
empty_frame_width
=
cm
->
width
;
cpi
->
svc
.
empty_frame_height
=
cm
->
height
;
}
}
else
{
cm
->
frame_type
=
INTER_FRAME
;
...
...
vp9/encoder/vp9_svc_layercontext.c
View file @
422cf740
...
...
@@ -14,6 +14,8 @@
#include
"vp9/encoder/vp9_svc_layercontext.h"
#include
"vp9/encoder/vp9_extend.h"
#define SMALL_FRAME_FB_IDX 7
void
vp9_init_layer_context
(
VP9_COMP
*
const
cpi
)
{
SVC
*
const
svc
=
&
cpi
->
svc
;
const
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
...
...
@@ -28,6 +30,25 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
layer_end
=
svc
->
number_temporal_layers
;
}
else
{
layer_end
=
svc
->
number_spatial_layers
;
if
(
cpi
->
oxcf
.
error_resilient_mode
==
0
&&
cpi
->
oxcf
.
pass
==
2
)
{
if
(
vp9_realloc_frame_buffer
(
&
cpi
->
svc
.
empty_frame
.
img
,
cpi
->
common
.
width
,
cpi
->
common
.
height
,
cpi
->
common
.
subsampling_x
,
cpi
->
common
.
subsampling_y
,
#if CONFIG_VP9_HIGHBITDEPTH
cpi
->
common
.
use_highbitdepth
,
#endif
VP9_ENC_BORDER_IN_PIXELS
,
NULL
,
NULL
,
NULL
))
vpx_internal_error
(
&
cpi
->
common
.
error
,
VPX_CODEC_MEM_ERROR
,
"Failed to allocate empty frame for multiple frame "
"contexts"
);
vpx_memset
(
cpi
->
svc
.
empty_frame
.
img
.
buffer_alloc
,
0x80
,
cpi
->
svc
.
empty_frame
.
img
.
buffer_alloc_sz
);
cpi
->
svc
.
empty_frame_width
=
cpi
->
common
.
width
;
cpi
->
svc
.
empty_frame_height
=
cpi
->
common
.
height
;
}
}
for
(
layer
=
0
;
layer
<
layer_end
;
++
layer
)
{
...
...
@@ -310,6 +331,47 @@ int vp9_svc_start_frame(VP9_COMP *const cpi) {
get_layer_resolution
(
cpi
->
oxcf
.
width
,
cpi
->
oxcf
.
height
,
lc
->
scaling_factor_num
,
lc
->
scaling_factor_den
,
&
width
,
&
height
);
// Workaround for multiple frame contexts. In some frames we can't use prev_mi
// since its previous frame could be changed during decoding time. The idea is
// we put a empty invisible frame in front of them, then we will not use
// prev_mi when encoding these frames.
if
(
cpi
->
oxcf
.
error_resilient_mode
==
0
&&
cpi
->
oxcf
.
pass
==
2
&&
cpi
->
svc
.
encode_empty_frame_state
==
NEED_TO_ENCODE
)
{
if
((
cpi
->
svc
.
number_temporal_layers
>
1
&&
cpi
->
svc
.
temporal_layer_id
<
cpi
->
svc
.
number_temporal_layers
-
1
)
||
(
cpi
->
svc
.
number_spatial_layers
>
1
&&
cpi
->
svc
.
spatial_layer_id
==
0
))
{
struct
lookahead_entry
*
buf
=
vp9_lookahead_peek
(
cpi
->
lookahead
,
0
);
if
(
buf
!=
NULL
)
{
cpi
->
svc
.
empty_frame
.
ts_start
=
buf
->
ts_start
;
cpi
->
svc
.
empty_frame
.
ts_end
=
buf
->
ts_end
;
cpi
->
svc
.
encode_empty_frame_state
=
ENCODING
;
cpi
->
common
.
show_frame
=
0
;
cpi
->
ref_frame_flags
=
0
;
cpi
->
common
.
frame_type
=
INTER_FRAME
;
cpi
->
lst_fb_idx
=
cpi
->
gld_fb_idx
=
cpi
->
alt_fb_idx
=
SMALL_FRAME_FB_IDX
;
// Gradually make the empty frame smaller to save bits. Make it half of
// its previous size because of the scaling factor restriction.
cpi
->
svc
.
empty_frame_width
>>=
1
;
cpi
->
svc
.
empty_frame_width
=
(
cpi
->
svc
.
empty_frame_width
+
1
)
&
~
1
;
if
(
cpi
->
svc
.
empty_frame_width
<
16
)
cpi
->
svc
.
empty_frame_width
=
16
;
cpi
->
svc
.
empty_frame_height
>>=
1
;
cpi
->
svc
.
empty_frame_height
=
(
cpi
->
svc
.
empty_frame_height
+
1
)
&
~
1
;
if
(
cpi
->
svc
.
empty_frame_height
<
16
)
cpi
->
svc
.
empty_frame_height
=
16
;
width
=
cpi
->
svc
.
empty_frame_width
;
height
=
cpi
->
svc
.
empty_frame_height
;
}
}
}
if
(
vp9_set_size_literal
(
cpi
,
width
,
height
)
!=
0
)
return
VPX_CODEC_INVALID_PARAM
;
...
...
@@ -317,7 +379,6 @@ int vp9_svc_start_frame(VP9_COMP *const cpi) {
cpi
->
oxcf
.
best_allowed_q
=
vp9_quantizer_to_qindex
(
lc
->
min_q
);
vp9_change_config
(
cpi
,
&
cpi
->
oxcf
);
vp9_set_high_precision_mv
(
cpi
,
1
);
cpi
->
alt_ref_source
=
get_layer_context
(
cpi
)
->
alt_ref_source
;
...
...
vp9/encoder/vp9_svc_layercontext.h
View file @
422cf740
...
...
@@ -50,6 +50,16 @@ typedef struct {
int
spatial_layer_to_encode
;
// Workaround for multiple frame contexts
enum
{
ENCODED
=
0
,
ENCODING
,
NEED_TO_ENCODE
}
encode_empty_frame_state
;
struct
lookahead_entry
empty_frame
;
int
empty_frame_width
;
int
empty_frame_height
;
// Store scaled source frames to be used for temporal filter to generate
// a alt ref frame.
YV12_BUFFER_CONFIG
scaled_frames
[
MAX_LAG_BUFFERS
];
...
...
vp9/encoder/vp9_temporal_filter.c
View file @
422cf740
...
...
@@ -719,6 +719,9 @@ void vp9_temporal_filter(VP9_COMP *cpi, int distance) {
++
frame_used
;
}
}
cm
->
mi
=
cm
->
mip
+
cm
->
mi_stride
+
1
;
cpi
->
mb
.
e_mbd
.
mi
=
cm
->
mi
;
cpi
->
mb
.
e_mbd
.
mi
[
0
].
src_mi
=
&
cpi
->
mb
.
e_mbd
.
mi
[
0
];
}
else
{
// ARF is produced at the native frame size and resized when coded.
#if CONFIG_VP9_HIGHBITDEPTH
...
...
vp9/vp9_cx_iface.c
View file @
422cf740
...
...
@@ -188,11 +188,9 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
}
if
(
alt_ref_sum
>
REF_FRAMES
-
cfg
->
ss_number_layers
)
ERROR
(
"Not enough ref buffers for svc alt ref frames"
);
if
((
cfg
->
ss_number_layers
>
3
||
cfg
->
ss_number_layers
*
cfg
->
ts_number_layers
>
4
)
&&
if
(
cfg
->
ss_number_layers
*
cfg
->
ts_number_layers
>
3
&&
cfg
->
g_error_resilient
==
0
)
ERROR
(
"Multiple frame context are not supported for more than 3 spatial "
"layers or more than 4 spatial x temporal layers"
);
ERROR
(
"Multiple frame context are not supported for more than 3 layers"
);
}
#endif
...
...
vpx/src/svc_encodeframe.c
View file @
422cf740
...
...
@@ -350,7 +350,7 @@ void assign_layer_bitrates(const SvcContext *svc_ctx,
}
}
for
(
i
=
0
;
i
<
svc_ctx
->
spatial_layers
;
++
i
)
{
for
(
i
=
0
;
i
<
VPX_SS_MAX_LAYERS
;
++
i
)
{
if
(
total
>
0
)
{
enc_cfg
->
ss_target_bitrate
[
i
]
=
(
unsigned
int
)
(
enc_cfg
->
rc_target_bitrate
*
alloc_ratio
[
i
]
/
total
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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