summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHangyu Kuang <hkuang@google.com>2014-07-31 19:04:35 -0700
committerHangyu Kuang <hkuang@google.com>2014-08-06 11:16:14 -0700
commit7050074756c0642ab2742a2a5db85d9ac5f4e5e0 (patch)
tree4d82e436ca0379f48c3e081692f19631982775b1
parentf94227c81d7278ddf9634bb91ee2d2e7cfe610e3 (diff)
downloadlibvpx-7050074756c0642ab2742a2a5db85d9ac5f4e5e0.tar
libvpx-7050074756c0642ab2742a2a5db85d9ac5f4e5e0.tar.gz
libvpx-7050074756c0642ab2742a2a5db85d9ac5f4e5e0.tar.bz2
libvpx-7050074756c0642ab2742a2a5db85d9ac5f4e5e0.zip
Make the api behavior conform to api spec.
When no more data is available, vpx_codec_decode should be called with NULL as data and 0 as data_sz. vpx_codec_get_frame iterates over a list of the frames available for display. The iterator storage should be initialized to NULL to start the iteration. Iteration is complete when this function returns NULL. Also change the unit test to conform to the api spec. Change-Id: I4b258b309f5df3d37d10c82f01492c0394181c2a
-rw-r--r--test/decode_test_driver.cc31
-rw-r--r--vp8/vp8_dx_iface.c9
-rw-r--r--vp9/vp9_dx_iface.c11
3 files changed, 38 insertions, 13 deletions
diff --git a/test/decode_test_driver.cc b/test/decode_test_driver.cc
index 3e4ef0ad1..99610ebc5 100644
--- a/test/decode_test_driver.cc
+++ b/test/decode_test_driver.cc
@@ -67,24 +67,33 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_codec_dec_cfg_t &dec_cfg) {
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
ASSERT_TRUE(decoder != NULL);
+ bool end_of_file = false;
// Decode frames.
- for (video->Begin(); !::testing::Test::HasFailure() && video->cxdata();
+ for (video->Begin(); !::testing::Test::HasFailure() && !end_of_file;
video->Next()) {
PreDecodeFrameHook(*video, decoder);
vpx_codec_stream_info_t stream_info;
stream_info.sz = sizeof(stream_info);
- const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(),
- video->frame_size(),
- &stream_info);
- HandlePeekResult(decoder, video, res_peek);
- ASSERT_FALSE(::testing::Test::HasFailure());
-
- vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
- video->frame_size());
- if (!HandleDecodeResult(res_dec, *video, decoder))
- break;
+
+ if (video->cxdata() != NULL) {
+ const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(),
+ video->frame_size(),
+ &stream_info);
+ HandlePeekResult(decoder, video, res_peek);
+ ASSERT_FALSE(::testing::Test::HasFailure());
+
+ vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
+ video->frame_size());
+ if (!HandleDecodeResult(res_dec, *video, decoder))
+ break;
+ } else {
+ // Signal end of the file to the decoder.
+ const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
+ ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
+ end_of_file = true;
+ }
DxDataIterator dec_iter = decoder->GetDxData();
const vpx_image_t *img = NULL;
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index f768b5c47..ccc0afbe3 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -60,6 +60,7 @@ struct vpx_codec_alg_priv
vpx_decrypt_cb decrypt_cb;
void *decrypt_state;
vpx_image_t img;
+ int flushed;
int img_setup;
struct frame_buffers yv12_frame_buffers;
void *user_priv;
@@ -88,6 +89,7 @@ static void vp8_init_ctx(vpx_codec_ctx_t *ctx)
ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
ctx->priv->alg_priv->decrypt_cb = NULL;
ctx->priv->alg_priv->decrypt_state = NULL;
+ ctx->priv->alg_priv->flushed = 0;
ctx->priv->init_flags = ctx->init_flags;
if (ctx->config.dec)
@@ -328,6 +330,13 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx,
unsigned int resolution_change = 0;
unsigned int w, h;
+ if (data == NULL && data_sz == 0) {
+ ctx->flushed = 1;
+ return VPX_CODEC_OK;
+ }
+
+ /* Reset flushed when receiving a valid frame */
+ ctx->flushed = 0;
/* Update the input fragment data */
if(update_fragments(ctx, data, data_sz, &res) <= 0)
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index c52884084..3ff3f6c76 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -40,6 +40,7 @@ struct vpx_codec_alg_priv {
void *decrypt_state;
vpx_image_t img;
int img_avail;
+ int flushed;
int invert_tile_order;
int frame_parallel_decode; // frame-based threading.
@@ -69,6 +70,7 @@ static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx,
ctx->priv->alg_priv = alg_priv;
ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
ctx->priv->init_flags = ctx->init_flags;
+ ctx->priv->alg_priv->flushed = 0;
ctx->priv->alg_priv->frame_parallel_decode =
(ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING);
@@ -403,8 +405,13 @@ static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
uint32_t frame_sizes[8];
int frame_count;
- if (data == NULL || data_sz == 0)
- return VPX_CODEC_INVALID_PARAM;
+ if (data == NULL && data_sz == 0) {
+ ctx->flushed = 1;
+ return VPX_CODEC_OK;
+ }
+
+ // Reset flushed when receiving a valid frame.
+ ctx->flushed = 0;
res = parse_superframe_index(data, data_sz, frame_sizes, &frame_count,
ctx->decrypt_cb, ctx->decrypt_state);