Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Xiph.Org
aom-rav1e
Commits
fb8c246b
Commit
fb8c246b
authored
Feb 13, 2014
by
Frank Galligan
Committed by
Gerrit Code Review
Feb 13, 2014
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Add VP9 decoder support for external frame buffers"
parents
e590e087
a4f30a50
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
720 additions
and
22 deletions
+720
-22
test/codec_factory.h
test/codec_factory.h
+2
-0
test/decode_test_driver.h
test/decode_test_driver.h
+9
-0
test/external_frame_buffer_test.cc
test/external_frame_buffer_test.cc
+466
-0
test/test.mk
test/test.mk
+1
-0
vp8/vp8_dx_iface.c
vp8/vp8_dx_iface.c
+1
-0
vp9/common/vp9_frame_buffers.c
vp9/common/vp9_frame_buffers.c
+2
-6
vp9/vp9_dx_iface.c
vp9/vp9_dx_iface.c
+43
-8
vpx/exports_dec
vpx/exports_dec
+1
-0
vpx/internal/vpx_codec_internal.h
vpx/internal/vpx_codec_internal.h
+32
-1
vpx/src/vpx_decoder.c
vpx/src/vpx_decoder.c
+18
-0
vpx/vpx_decoder.h
vpx/vpx_decoder.h
+49
-1
vpx/vpx_frame_buffer.h
vpx/vpx_frame_buffer.h
+6
-4
vpx/vpx_image.h
vpx/vpx_image.h
+3
-1
vpxdec.c
vpxdec.c
+87
-1
No files found.
test/codec_factory.h
View file @
fb8c246b
...
...
@@ -24,6 +24,8 @@
#include "test/encode_test_driver.h"
namespace
libvpx_test
{
const
int
kCodecFactoryParam
=
0
;
class
CodecFactory
{
public:
CodecFactory
()
{}
...
...
test/decode_test_driver.h
View file @
fb8c246b
...
...
@@ -76,6 +76,15 @@ class Decoder {
return
detail
?
detail
:
vpx_codec_error
(
&
decoder_
);
}
// Passes the external frame buffer information to libvpx.
vpx_codec_err_t
SetFrameBufferFunctions
(
vpx_get_frame_buffer_cb_fn_t
cb_get
,
vpx_release_frame_buffer_cb_fn_t
cb_release
,
void
*
user_priv
)
{
InitOnce
();
return
vpx_codec_set_frame_buffer_functions
(
&
decoder_
,
cb_get
,
cb_release
,
user_priv
);
}
protected:
virtual
vpx_codec_iface_t
*
CodecInterface
()
const
=
0
;
...
...
test/external_frame_buffer_test.cc
0 → 100644
View file @
fb8c246b
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string>
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/ivf_video_source.h"
#include "test/md5_helper.h"
#include "test/test_vectors.h"
#include "test/util.h"
#include "test/webm_video_source.h"
namespace
{
const
int
kVideoNameParam
=
1
;
const
char
kVP9TestFile
[]
=
"vp90-2-02-size-lf-1920x1080.webm"
;
struct
ExternalFrameBuffer
{
uint8_t
*
data
;
size_t
size
;
int
in_use
;
};
// Class to manipulate a list of external frame buffers.
class
ExternalFrameBufferList
{
public:
ExternalFrameBufferList
()
:
num_buffers_
(
0
),
ext_fb_list_
(
NULL
)
{}
virtual
~
ExternalFrameBufferList
()
{
for
(
int
i
=
0
;
i
<
num_buffers_
;
++
i
)
{
delete
[]
ext_fb_list_
[
i
].
data
;
}
delete
[]
ext_fb_list_
;
}
// Creates the list to hold the external buffers. Returns true on success.
bool
CreateBufferList
(
int
num_buffers
)
{
if
(
num_buffers
<
0
)
return
false
;
num_buffers_
=
num_buffers
;
ext_fb_list_
=
new
ExternalFrameBuffer
[
num_buffers_
];
EXPECT_TRUE
(
ext_fb_list_
!=
NULL
);
memset
(
ext_fb_list_
,
0
,
sizeof
(
ext_fb_list_
[
0
])
*
num_buffers_
);
return
true
;
}
// Searches the frame buffer list for a free frame buffer. Makes sure
// that the frame buffer is at least |min_size| in bytes. Marks that the
// frame buffer is in use by libvpx. Finally sets |fb| to point to the
// external frame buffer. Returns < 0 on an error.
int
GetFreeFrameBuffer
(
size_t
min_size
,
vpx_codec_frame_buffer_t
*
fb
)
{
EXPECT_TRUE
(
fb
!=
NULL
);
const
int
idx
=
FindFreeBufferIndex
();
if
(
idx
==
num_buffers_
)
return
-
1
;
if
(
ext_fb_list_
[
idx
].
size
<
min_size
)
{
delete
[]
ext_fb_list_
[
idx
].
data
;
ext_fb_list_
[
idx
].
data
=
new
uint8_t
[
min_size
];
ext_fb_list_
[
idx
].
size
=
min_size
;
}
SetFrameBuffer
(
idx
,
fb
);
return
0
;
}
// Test function that will not allocate any data for the frame buffer.
// Returns < 0 on an error.
int
GetZeroFrameBuffer
(
size_t
min_size
,
vpx_codec_frame_buffer_t
*
fb
)
{
EXPECT_TRUE
(
fb
!=
NULL
);
const
int
idx
=
FindFreeBufferIndex
();
if
(
idx
==
num_buffers_
)
return
-
1
;
if
(
ext_fb_list_
[
idx
].
size
<
min_size
)
{
delete
[]
ext_fb_list_
[
idx
].
data
;
ext_fb_list_
[
idx
].
data
=
NULL
;
ext_fb_list_
[
idx
].
size
=
min_size
;
}
SetFrameBuffer
(
idx
,
fb
);
return
0
;
}
// Marks the external frame buffer that |fb| is pointing too as free.
// Returns < 0 on an error.
int
ReturnFrameBuffer
(
vpx_codec_frame_buffer_t
*
fb
)
{
EXPECT_TRUE
(
fb
!=
NULL
);
ExternalFrameBuffer
*
const
ext_fb
=
reinterpret_cast
<
ExternalFrameBuffer
*>
(
fb
->
priv
);
EXPECT_TRUE
(
ext_fb
!=
NULL
);
EXPECT_EQ
(
1
,
ext_fb
->
in_use
);
ext_fb
->
in_use
=
0
;
return
0
;
}
// Checks that the ximage data is contained within the external frame buffer
// private data passed back in the ximage.
void
CheckXImageFrameBuffer
(
const
vpx_image_t
*
img
)
{
if
(
img
->
fb_priv
!=
NULL
)
{
const
struct
ExternalFrameBuffer
*
const
ext_fb
=
reinterpret_cast
<
ExternalFrameBuffer
*>
(
img
->
fb_priv
);
ASSERT_TRUE
(
img
->
planes
[
0
]
>=
ext_fb
->
data
&&
img
->
planes
[
0
]
<
(
ext_fb
->
data
+
ext_fb
->
size
));
}
}
private:
// Returns the index of the first free frame buffer. Returns |num_buffers_|
// if there are no free frame buffers.
int
FindFreeBufferIndex
()
{
int
i
;
// Find a free frame buffer.
for
(
i
=
0
;
i
<
num_buffers_
;
++
i
)
{
if
(
!
ext_fb_list_
[
i
].
in_use
)
break
;
}
return
i
;
}
// Sets |fb| to an external frame buffer. idx is the index into the frame
// buffer list.
void
SetFrameBuffer
(
int
idx
,
vpx_codec_frame_buffer_t
*
fb
)
{
ASSERT_TRUE
(
fb
!=
NULL
);
fb
->
data
=
ext_fb_list_
[
idx
].
data
;
fb
->
size
=
ext_fb_list_
[
idx
].
size
;
ASSERT_EQ
(
0
,
ext_fb_list_
[
idx
].
in_use
);
ext_fb_list_
[
idx
].
in_use
=
1
;
fb
->
priv
=
&
ext_fb_list_
[
idx
];
}
int
num_buffers_
;
ExternalFrameBuffer
*
ext_fb_list_
;
};
// Callback used by libvpx to request the application to return a frame
// buffer of at least |min_size| in bytes.
int
get_vp9_frame_buffer
(
void
*
user_priv
,
size_t
min_size
,
vpx_codec_frame_buffer_t
*
fb
)
{
ExternalFrameBufferList
*
const
fb_list
=
reinterpret_cast
<
ExternalFrameBufferList
*>
(
user_priv
);
return
fb_list
->
GetFreeFrameBuffer
(
min_size
,
fb
);
}
// Callback used by libvpx to tell the application that |fb| is not needed
// anymore.
int
release_vp9_frame_buffer
(
void
*
user_priv
,
vpx_codec_frame_buffer_t
*
fb
)
{
ExternalFrameBufferList
*
const
fb_list
=
reinterpret_cast
<
ExternalFrameBufferList
*>
(
user_priv
);
return
fb_list
->
ReturnFrameBuffer
(
fb
);
}
// Callback will not allocate data for frame buffer.
int
get_vp9_zero_frame_buffer
(
void
*
user_priv
,
size_t
min_size
,
vpx_codec_frame_buffer_t
*
fb
)
{
ExternalFrameBufferList
*
const
fb_list
=
reinterpret_cast
<
ExternalFrameBufferList
*>
(
user_priv
);
return
fb_list
->
GetZeroFrameBuffer
(
min_size
,
fb
);
}
// Callback will allocate one less byte than |min_size|.
int
get_vp9_one_less_byte_frame_buffer
(
void
*
user_priv
,
size_t
min_size
,
vpx_codec_frame_buffer_t
*
fb
)
{
ExternalFrameBufferList
*
const
fb_list
=
reinterpret_cast
<
ExternalFrameBufferList
*>
(
user_priv
);
return
fb_list
->
GetFreeFrameBuffer
(
min_size
-
1
,
fb
);
}
// Callback will not release the external frame buffer.
int
do_not_release_vp9_frame_buffer
(
void
*
user_priv
,
vpx_codec_frame_buffer_t
*
fb
)
{
(
void
)
user_priv
;
(
void
)
fb
;
return
0
;
}
// Class for testing passing in external frame buffers to libvpx.
class
ExternalFrameBufferMD5Test
:
public
::
libvpx_test
::
DecoderTest
,
public
::
libvpx_test
::
CodecTestWithParam
<
const
char
*>
{
protected:
ExternalFrameBufferMD5Test
()
:
DecoderTest
(
GET_PARAM
(
::
libvpx_test
::
kCodecFactoryParam
)),
md5_file_
(
NULL
),
num_buffers_
(
0
)
{}
virtual
~
ExternalFrameBufferMD5Test
()
{
if
(
md5_file_
!=
NULL
)
fclose
(
md5_file_
);
}
virtual
void
PreDecodeFrameHook
(
const
libvpx_test
::
CompressedVideoSource
&
video
,
libvpx_test
::
Decoder
*
decoder
)
{
if
(
num_buffers_
>
0
&&
video
.
frame_number
()
==
0
)
{
// Have libvpx use frame buffers we create.
ASSERT_TRUE
(
fb_list_
.
CreateBufferList
(
num_buffers_
));
ASSERT_EQ
(
VPX_CODEC_OK
,
decoder
->
SetFrameBufferFunctions
(
GetVp9FrameBuffer
,
ReleaseVP9FrameBuffer
,
this
));
}
}
void
OpenMD5File
(
const
std
::
string
&
md5_file_name_
)
{
md5_file_
=
libvpx_test
::
OpenTestDataFile
(
md5_file_name_
);
ASSERT_TRUE
(
md5_file_
!=
NULL
)
<<
"Md5 file open failed. Filename: "
<<
md5_file_name_
;
}
virtual
void
DecompressedFrameHook
(
const
vpx_image_t
&
img
,
const
unsigned
int
frame_number
)
{
ASSERT_TRUE
(
md5_file_
!=
NULL
);
char
expected_md5
[
33
];
char
junk
[
128
];
// Read correct md5 checksums.
const
int
res
=
fscanf
(
md5_file_
,
"%s %s"
,
expected_md5
,
junk
);
ASSERT_NE
(
EOF
,
res
)
<<
"Read md5 data failed"
;
expected_md5
[
32
]
=
'\0'
;
::
libvpx_test
::
MD5
md5_res
;
md5_res
.
Add
(
&
img
);
const
char
*
const
actual_md5
=
md5_res
.
Get
();
// Check md5 match.
ASSERT_STREQ
(
expected_md5
,
actual_md5
)
<<
"Md5 checksums don't match: frame number = "
<<
frame_number
;
}
// Callback to get a free external frame buffer. Return value < 0 is an
// error.
static
int
GetVp9FrameBuffer
(
void
*
user_priv
,
size_t
min_size
,
vpx_codec_frame_buffer_t
*
fb
)
{
ExternalFrameBufferMD5Test
*
const
md5Test
=
reinterpret_cast
<
ExternalFrameBufferMD5Test
*>
(
user_priv
);
return
md5Test
->
fb_list_
.
GetFreeFrameBuffer
(
min_size
,
fb
);
}
// Callback to release an external frame buffer. Return value < 0 is an
// error.
static
int
ReleaseVP9FrameBuffer
(
void
*
user_priv
,
vpx_codec_frame_buffer_t
*
fb
)
{
ExternalFrameBufferMD5Test
*
const
md5Test
=
reinterpret_cast
<
ExternalFrameBufferMD5Test
*>
(
user_priv
);
return
md5Test
->
fb_list_
.
ReturnFrameBuffer
(
fb
);
}
void
set_num_buffers
(
int
num_buffers
)
{
num_buffers_
=
num_buffers
;
}
int
num_buffers
()
const
{
return
num_buffers_
;
}
private:
FILE
*
md5_file_
;
int
num_buffers_
;
ExternalFrameBufferList
fb_list_
;
};
// Class for testing passing in external frame buffers to libvpx.
class
ExternalFrameBufferTest
:
public
::
testing
::
Test
{
protected:
ExternalFrameBufferTest
()
:
video_
(
NULL
),
decoder_
(
NULL
),
num_buffers_
(
0
)
{}
virtual
void
SetUp
()
{
video_
=
new
libvpx_test
::
WebMVideoSource
(
kVP9TestFile
);
ASSERT_TRUE
(
video_
!=
NULL
);
video_
->
Init
();
video_
->
Begin
();
vpx_codec_dec_cfg_t
cfg
=
{
0
};
decoder_
=
new
libvpx_test
::
VP9Decoder
(
cfg
,
0
);
ASSERT_TRUE
(
decoder_
!=
NULL
);
}
virtual
void
TearDown
()
{
delete
decoder_
;
delete
video_
;
}
// Passes the external frame buffer information to libvpx.
vpx_codec_err_t
SetFrameBufferFunctions
(
int
num_buffers
,
vpx_get_frame_buffer_cb_fn_t
cb_get
,
vpx_release_frame_buffer_cb_fn_t
cb_release
)
{
if
(
num_buffers
>
0
)
{
num_buffers_
=
num_buffers
;
EXPECT_TRUE
(
fb_list_
.
CreateBufferList
(
num_buffers_
));
}
return
decoder_
->
SetFrameBufferFunctions
(
cb_get
,
cb_release
,
&
fb_list_
);
}
vpx_codec_err_t
DecodeOneFrame
()
{
const
vpx_codec_err_t
res
=
decoder_
->
DecodeFrame
(
video_
->
cxdata
(),
video_
->
frame_size
());
CheckDecodedFrames
();
if
(
res
==
VPX_CODEC_OK
)
video_
->
Next
();
return
res
;
}
vpx_codec_err_t
DecodeRemainingFrames
()
{
for
(;
video_
->
cxdata
()
!=
NULL
;
video_
->
Next
())
{
const
vpx_codec_err_t
res
=
decoder_
->
DecodeFrame
(
video_
->
cxdata
(),
video_
->
frame_size
());
if
(
res
!=
VPX_CODEC_OK
)
return
res
;
CheckDecodedFrames
();
}
return
VPX_CODEC_OK
;
}
private:
void
CheckDecodedFrames
()
{
libvpx_test
::
DxDataIterator
dec_iter
=
decoder_
->
GetDxData
();
const
vpx_image_t
*
img
=
NULL
;
// Get decompressed data
while
((
img
=
dec_iter
.
Next
())
!=
NULL
)
{
fb_list_
.
CheckXImageFrameBuffer
(
img
);
}
}
libvpx_test
::
WebMVideoSource
*
video_
;
libvpx_test
::
VP9Decoder
*
decoder_
;
int
num_buffers_
;
ExternalFrameBufferList
fb_list_
;
};
// This test runs through the set of test vectors, and decodes them.
// Libvpx will call into the application to allocate a frame buffer when
// needed. The md5 checksums are computed for each frame in the video file.
// If md5 checksums match the correct md5 data, then the test is passed.
// Otherwise, the test failed.
TEST_P
(
ExternalFrameBufferMD5Test
,
ExtFBMD5Match
)
{
const
std
::
string
filename
=
GET_PARAM
(
kVideoNameParam
);
libvpx_test
::
CompressedVideoSource
*
video
=
NULL
;
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
const
int
jitter_buffers
=
4
;
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
+
jitter_buffers
;
set_num_buffers
(
num_buffers
);
#if CONFIG_VP8_DECODER
// Tell compiler we are not using kVP8TestVectors.
(
void
)
libvpx_test
::
kVP8TestVectors
;
#endif
// Open compressed video file.
if
(
filename
.
substr
(
filename
.
length
()
-
3
,
3
)
==
"ivf"
)
{
video
=
new
libvpx_test
::
IVFVideoSource
(
filename
);
}
else
{
video
=
new
libvpx_test
::
WebMVideoSource
(
filename
);
}
ASSERT_TRUE
(
video
!=
NULL
);
video
->
Init
();
// Construct md5 file name.
const
std
::
string
md5_filename
=
filename
+
".md5"
;
OpenMD5File
(
md5_filename
);
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE
(
RunLoop
(
video
));
delete
video
;
}
TEST_F
(
ExternalFrameBufferTest
,
MinFrameBuffers
)
{
// Minimum number of external frame buffers for VP9 is
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_OK
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_frame_buffer
,
release_vp9_frame_buffer
));
ASSERT_EQ
(
VPX_CODEC_OK
,
DecodeRemainingFrames
());
}
TEST_F
(
ExternalFrameBufferTest
,
EightJitterBuffers
)
{
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
// #VPX_MAXIMUM_WORK_BUFFERS + eight jitter buffers.
const
int
jitter_buffers
=
8
;
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
+
jitter_buffers
;
ASSERT_EQ
(
VPX_CODEC_OK
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_frame_buffer
,
release_vp9_frame_buffer
));
ASSERT_EQ
(
VPX_CODEC_OK
,
DecodeRemainingFrames
());
}
TEST_F
(
ExternalFrameBufferTest
,
NotEnoughBuffers
)
{
// Minimum number of external frame buffers for VP9 is
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. Most files will
// only use 5 frame buffers at one time.
const
int
num_buffers
=
2
;
ASSERT_EQ
(
VPX_CODEC_OK
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_frame_buffer
,
release_vp9_frame_buffer
));
ASSERT_EQ
(
VPX_CODEC_OK
,
DecodeOneFrame
());
ASSERT_EQ
(
VPX_CODEC_MEM_ERROR
,
DecodeRemainingFrames
());
}
TEST_F
(
ExternalFrameBufferTest
,
NoRelease
)
{
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_OK
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_frame_buffer
,
do_not_release_vp9_frame_buffer
));
ASSERT_EQ
(
VPX_CODEC_OK
,
DecodeOneFrame
());
ASSERT_EQ
(
VPX_CODEC_MEM_ERROR
,
DecodeRemainingFrames
());
}
TEST_F
(
ExternalFrameBufferTest
,
NullRealloc
)
{
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_OK
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_zero_frame_buffer
,
release_vp9_frame_buffer
));
ASSERT_EQ
(
VPX_CODEC_MEM_ERROR
,
DecodeOneFrame
());
}
TEST_F
(
ExternalFrameBufferTest
,
ReallocOneLessByte
)
{
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_OK
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_one_less_byte_frame_buffer
,
release_vp9_frame_buffer
));
ASSERT_EQ
(
VPX_CODEC_MEM_ERROR
,
DecodeOneFrame
());
}
TEST_F
(
ExternalFrameBufferTest
,
NullGetFunction
)
{
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_INVALID_PARAM
,
SetFrameBufferFunctions
(
num_buffers
,
NULL
,
release_vp9_frame_buffer
));
}
TEST_F
(
ExternalFrameBufferTest
,
NullReleaseFunction
)
{
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_INVALID_PARAM
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_frame_buffer
,
NULL
));
}
TEST_F
(
ExternalFrameBufferTest
,
SetAfterDecode
)
{
const
int
num_buffers
=
VP9_MAXIMUM_REF_BUFFERS
+
VPX_MAXIMUM_WORK_BUFFERS
;
ASSERT_EQ
(
VPX_CODEC_OK
,
DecodeOneFrame
());
ASSERT_EQ
(
VPX_CODEC_ERROR
,
SetFrameBufferFunctions
(
num_buffers
,
get_vp9_frame_buffer
,
release_vp9_frame_buffer
));
}
VP9_INSTANTIATE_TEST_CASE
(
ExternalFrameBufferMD5Test
,
::
testing
::
ValuesIn
(
libvpx_test
::
kVP9TestVectors
));
}
// namespace
test/test.mk
View file @
fb8c246b
...
...
@@ -36,6 +36,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../md5_utils.h ../md5_utils.c
LIBVPX_TEST_SRCS-yes
+=
decode_test_driver.cc
LIBVPX_TEST_SRCS-yes
+=
decode_test_driver.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS)
+=
ivf_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER)
+=
external_frame_buffer_test.cc
## WebM Parsing
NESTEGG_SRCS
+=
../nestegg/halloc/halloc.h
...
...
vp8/vp8_dx_iface.c
View file @
fb8c246b
...
...
@@ -929,6 +929,7 @@ CODEC_INTERFACE(vpx_codec_vp8_dx) =
vp8_get_si
,
/* vpx_codec_get_si_fn_t get_si; */
vp8_decode
,
/* vpx_codec_decode_fn_t decode; */
vp8_get_frame
,
/* vpx_codec_frame_get_fn_t frame_get; */
NOT_IMPLEMENTED
,
},
{
/* encoder functions */
NOT_IMPLEMENTED
,
...
...
vp9/common/vp9_frame_buffers.c
View file @
fb8c246b
...
...
@@ -42,7 +42,7 @@ int vp9_get_frame_buffer(void *cb_priv, size_t min_size,
int
i
;
InternalFrameBufferList
*
const
int_fb_list
=
(
InternalFrameBufferList
*
)
cb_priv
;
if
(
int_fb_list
==
NULL
||
fb
==
NULL
)
if
(
int_fb_list
==
NULL
)
return
-
1
;
// Find a free frame buffer.
...
...
@@ -73,12 +73,8 @@ int vp9_get_frame_buffer(void *cb_priv, size_t min_size,
}
int
vp9_release_frame_buffer
(
void
*
cb_priv
,
vpx_codec_frame_buffer_t
*
fb
)
{
InternalFrameBuffer
*
int_fb
;
InternalFrameBuffer
*
const
int_fb
=
(
InternalFrameBuffer
*
)
fb
->
priv
;
(
void
)
cb_priv
;
if
(
fb
==
NULL
)
return
-
1
;
int_fb
=
(
InternalFrameBuffer
*
)
fb
->
priv
;
int_fb
->
in_use
=
0
;
return
0
;
}
vp9/vp9_dx_iface.c
View file @
fb8c246b
...
...
@@ -60,6 +60,11 @@ struct vpx_codec_alg_priv {
int
img_setup
;
int
img_avail
;
int
invert_tile_order
;
// External frame buffer info to save for VP9 common.
void
*
ext_priv
;
// Private data associated with the external frame buffers.
vpx_get_frame_buffer_cb_fn_t
get_ext_fb_cb
;
vpx_release_frame_buffer_cb_fn_t
release_ext_fb_cb
;
};
static
unsigned
long
priv_sz
(
const
vpx_codec_dec_cfg_t
*
si
,
...
...
@@ -300,16 +305,22 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
VP9D_COMP
*
const
pbi
=
(
VP9D_COMP
*
)
optr
;
VP9_COMMON
*
const
cm
=
&
pbi
->
common
;
cm
->
get_fb_cb
=
vp9_get_frame_buffer
;
cm
->
release_fb_cb
=
vp9_release_frame_buffer
;
// Set index to not initialized.
cm
->
new_fb_idx
=
-
1
;
if
(
vp9_alloc_internal_frame_buffers
(
&
cm
->
int_frame_buffers
))
vpx_internal_error
(
&
cm
->
error
,
VPX_CODEC_MEM_ERROR
,
"Failed to initialize internal frame buffers"
);
cm
->
cb_priv
=
&
cm
->
int_frame_buffers
;
if
(
ctx
->
get_ext_fb_cb
!=
NULL
&&
ctx
->
release_ext_fb_cb
!=
NULL
)
{
cm
->
get_fb_cb
=
ctx
->
get_ext_fb_cb
;
cm
->
release_fb_cb
=
ctx
->
release_ext_fb_cb
;
cm
->
cb_priv
=
ctx
->
ext_priv
;
}
else
{
cm
->
get_fb_cb
=
vp9_get_frame_buffer
;
cm
->
release_fb_cb
=
vp9_release_frame_buffer
;
if
(
vp9_alloc_internal_frame_buffers
(
&
cm
->
int_frame_buffers
))
vpx_internal_error
(
&
cm
->
error
,
VPX_CODEC_MEM_ERROR
,
"Failed to initialize internal frame buffers"
);
cm
->
cb_priv
=
&
cm
->
int_frame_buffers
;
}
ctx
->
pbi
=
optr
;
}
...
...
@@ -350,7 +361,11 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
if
(
!
res
&&
0
==
vp9_get_raw_frame
(
ctx
->
pbi
,
&
sd
,
&
time_stamp
,
&
time_end_stamp
,
&
flags
))
{
VP9D_COMP
*
const
pbi
=
(
VP9D_COMP
*
)
ctx
->
pbi
;
VP9_COMMON
*
const
cm
=
&
pbi
->
common
;
yuvconfig2image
(
&
ctx
->
img
,
&
sd
,
user_priv
);
ctx
->
img
.
fb_priv
=
cm
->
frame_bufs
[
cm
->
new_fb_idx
].
raw_frame_buffer
.
priv
;
ctx
->
img_avail
=
1
;
}
}
...
...
@@ -470,6 +485,24 @@ static vpx_image_t *vp9_get_frame(vpx_codec_alg_priv_t *ctx,
return
img
;
}
static
vpx_codec_err_t
vp9_set_fb_fn
(
vpx_codec_alg_priv_t
*
ctx
,
vpx_get_frame_buffer_cb_fn_t
cb_get
,
vpx_release_frame_buffer_cb_fn_t
cb_release
,
void
*
cb_priv
)
{
if
(
cb_get
==
NULL
||
cb_release
==
NULL
)
{
return
VPX_CODEC_INVALID_PARAM
;
}
else
if
(
ctx
->
pbi
==
NULL
)
{
// If the decoder has already been initialized, do not accept changes to
// the frame buffer functions.
ctx
->
get_ext_fb_cb
=
cb_get
;
ctx
->
release_ext_fb_cb
=
cb_release
;
ctx
->
ext_priv
=
cb_priv
;
return
VPX_CODEC_OK
;
}
return
VPX_CODEC_ERROR
;
}
static
vpx_codec_err_t
vp9_xma_get_mmap
(
const
vpx_codec_ctx_t
*
ctx
,
vpx_codec_mmap_t
*
mmap
,