]> granicus.if.org Git - libvpx/commitdiff
Manually pick "Make the api behavior conform to api spec." from
authorhkuang <hkuang@google.com>
Thu, 7 Aug 2014 21:29:41 +0000 (14:29 -0700)
committerhkuang <hkuang@google.com>
Thu, 7 Aug 2014 22:15:46 +0000 (15:15 -0700)
master branch.

Change-Id: I7323ec4cf8b8b7841e37f2bf90548cefa9de9795

test/decode_test_driver.cc
vp8/vp8_dx_iface.c
vp9/vp9_dx_iface.c

index 8bea4ccf9b19875a548b0139278bb76addfeb359..161dbb2628ea35df41eaa72b68ed394e6f81a1b6 100644 (file)
@@ -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;
 
index 56394fb1ca81f57c7a01049719bcaff9ad1b96d2..d5e319e8dd4676cb02dd9eb3358b17955b679d0b 100644 (file)
@@ -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)
index 746fab00670bec6df5a674420b13b4a6d5ad5728..3bfdea6ad57c273c60ecf1810d469a6d3c5f5e82 100644 (file)
@@ -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);