From 48c5d470e78436a6abde1c14c183f1a9d30f04de Mon Sep 17 00:00:00 2001 From: hkuang Date: Thu, 7 Aug 2014 14:29:41 -0700 Subject: [PATCH] Manually pick "Make the api behavior conform to api spec." from master branch. Change-Id: I7323ec4cf8b8b7841e37f2bf90548cefa9de9795 --- test/decode_test_driver.cc | 45 +++++++++++++++++++++++--------------- vp8/vp8_dx_iface.c | 9 ++++++++ vp9/vp9_dx_iface.c | 11 ++++++++-- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/test/decode_test_driver.cc b/test/decode_test_driver.cc index 8bea4ccf9..161dbb262 100644 --- a/test/decode_test_driver.cc +++ b/test/decode_test_driver.cc @@ -45,36 +45,45 @@ void DecoderTest::RunLoop(CompressedVideoSource *video) { ASSERT_TRUE(decoder != NULL); const char *codec_name = decoder->GetDecoderName(); const bool is_vp8 = strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0; + 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); - if (is_vp8) { - /* Vp8's implementation of PeekStream returns an error if the frame you - * pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first - * frame, which must be a keyframe. */ - if (video->frame_number() == 0) + + if (video->cxdata() != NULL) { + const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(), + video->frame_size(), + &stream_info); + if (is_vp8) { + /* Vp8's implementation of PeekStream returns an error if the frame you + * pass it is not a keyframe, so we only expect VPX_CODEC_OK on the + * first frame, which must be a keyframe. */ + if (video->frame_number() == 0) + ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: " + << vpx_codec_err_to_string(res_peek); + } else { + /* The Vp9 implementation of PeekStream returns an error only if the + * data passed to it isn't a valid Vp9 chunk. */ ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: " << vpx_codec_err_to_string(res_peek); + } + + vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(), + video->frame_size()); + if (!HandleDecodeResult(res_dec, *video, decoder)) + break; } else { - /* The Vp9 implementation of PeekStream returns an error only if the - * data passed to it isn't a valid Vp9 chunk. */ - ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: " - << vpx_codec_err_to_string(res_peek); + // 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; } - vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(), - video->frame_size()); - if (!HandleDecodeResult(res_dec, *video, decoder)) - break; - 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 56394fb1c..d5e319e8d 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; @@ -89,6 +90,7 @@ static void vp8_init_ctx(vpx_codec_ctx_t *ctx) ctx->priv->alg_priv->decrypt_cb = NULL; ctx->priv->alg_priv->decrypt_state = NULL; ctx->priv->init_flags = ctx->init_flags; + ctx->priv->alg_priv->flushed = 0; if (ctx->config.dec) { @@ -327,6 +329,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 746fab006..3bfdea6ad 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -37,6 +37,7 @@ struct vpx_codec_alg_priv { vpx_decrypt_cb decrypt_cb; void *decrypt_state; vpx_image_t img; + int flushed; int invert_tile_order; int frame_parallel_decode; // frame-based threading. int last_show_frame; // Index of last output frame. @@ -75,6 +76,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); @@ -468,8 +470,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); -- 2.40.0