shithub: libvpx

Download patch

ref: 48c5d470e78436a6abde1c14c183f1a9d30f04de
parent: 44395a21da75a8fa6ca71a39bee1c9fe55a1358e
author: hkuang <[email protected]>
date: Thu Aug 7 10:29:41 EDT 2014

Manually pick "Make the api behavior conform to api spec." from
master branch.

Change-Id: I7323ec4cf8b8b7841e37f2bf90548cefa9de9795

--- a/test/decode_test_driver.cc
+++ b/test/decode_test_driver.cc
@@ -45,35 +45,44 @@
   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;
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -60,6 +60,7 @@
     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 @@
     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 @@
     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)
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -37,6 +37,7 @@
   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 @@
     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 @@
   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);