Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "third_party/googletest/src/include/gtest/gtest.h"
     12 
     13 #include "./vpx_config.h"
     14 #include "test/ivf_video_source.h"
     15 #include "vpx/vp8dx.h"
     16 #include "vpx/vpx_decoder.h"
     17 
     18 namespace {
     19 
     20 #define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
     21 
     22 TEST(DecodeAPI, InvalidParams) {
     23   static const vpx_codec_iface_t *kCodecs[] = {
     24 #if CONFIG_VP8_DECODER
     25     &vpx_codec_vp8_dx_algo,
     26 #endif
     27 #if CONFIG_VP9_DECODER
     28     &vpx_codec_vp9_dx_algo,
     29 #endif
     30   };
     31   uint8_t buf[1] = { 0 };
     32   vpx_codec_ctx_t dec;
     33 
     34   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(NULL, NULL, NULL, 0));
     35   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(&dec, NULL, NULL, 0));
     36   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, NULL, 0, NULL, 0));
     37   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, buf, 0, NULL, 0));
     38   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
     39             vpx_codec_decode(NULL, buf, NELEMENTS(buf), NULL, 0));
     40   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
     41             vpx_codec_decode(NULL, NULL, NELEMENTS(buf), NULL, 0));
     42   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
     43   EXPECT_TRUE(vpx_codec_error(NULL) != NULL);
     44 
     45   for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
     46     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
     47               vpx_codec_dec_init(NULL, kCodecs[i], NULL, 0));
     48 
     49     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, kCodecs[i], NULL, 0));
     50     EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
     51               vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
     52     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
     53               vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
     54     EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(&dec, buf, 0, NULL, 0));
     55 
     56     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
     57   }
     58 }
     59 
     60 #if CONFIG_VP8_DECODER
     61 TEST(DecodeAPI, OptionalParams) {
     62   vpx_codec_ctx_t dec;
     63 
     64 #if CONFIG_ERROR_CONCEALMENT
     65   EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
     66                                              VPX_CODEC_USE_ERROR_CONCEALMENT));
     67 #else
     68   EXPECT_EQ(VPX_CODEC_INCAPABLE,
     69             vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
     70                                VPX_CODEC_USE_ERROR_CONCEALMENT));
     71 #endif  // CONFIG_ERROR_CONCEALMENT
     72 }
     73 #endif  // CONFIG_VP8_DECODER
     74 
     75 #if CONFIG_VP9_DECODER
     76 // Test VP9 codec controls after a decode error to ensure the code doesn't
     77 // misbehave.
     78 void TestVp9Controls(vpx_codec_ctx_t *dec) {
     79   static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES,
     80                                    VP8D_GET_FRAME_CORRUPTED,
     81                                    VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE };
     82   int val[2];
     83 
     84   for (int i = 0; i < NELEMENTS(kControls); ++i) {
     85     const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
     86     switch (kControls[i]) {
     87       case VP8D_GET_FRAME_CORRUPTED:
     88         EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
     89         break;
     90       default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
     91     }
     92     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
     93               vpx_codec_control_(dec, kControls[i], NULL));
     94   }
     95 
     96   vp9_ref_frame_t ref;
     97   ref.idx = 0;
     98   EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
     99   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
    100             vpx_codec_control(dec, VP9_GET_REFERENCE, NULL));
    101 
    102   vpx_ref_frame_t ref_copy;
    103   const int width = 352;
    104   const int height = 288;
    105   ASSERT_TRUE(
    106       vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1) != NULL);
    107   ref_copy.frame_type = VP8_LAST_FRAME;
    108   EXPECT_EQ(VPX_CODEC_ERROR,
    109             vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
    110   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
    111             vpx_codec_control(dec, VP8_COPY_REFERENCE, NULL));
    112   vpx_img_free(&ref_copy.img);
    113 }
    114 
    115 TEST(DecodeAPI, Vp9InvalidDecode) {
    116   const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
    117   const char filename[] =
    118       "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
    119   libvpx_test::IVFVideoSource video(filename);
    120   video.Init();
    121   video.Begin();
    122   ASSERT_TRUE(!HasFailure());
    123 
    124   vpx_codec_ctx_t dec;
    125   EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
    126   const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
    127 #if CONFIG_VP9_HIGHBITDEPTH
    128   EXPECT_EQ(VPX_CODEC_MEM_ERROR,
    129             vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
    130 #else
    131   EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
    132             vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
    133 #endif
    134   vpx_codec_iter_t iter = NULL;
    135   EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
    136 
    137   TestVp9Controls(&dec);
    138   EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
    139 }
    140 
    141 TEST(DecodeAPI, Vp9PeekSI) {
    142   const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
    143   // The first 9 bytes are valid and the rest of the bytes are made up. Until
    144   // size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
    145   // should return VPX_CODEC_CORRUPT_FRAME.
    146   const uint8_t data[32] = {
    147     0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff,
    148     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    149     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    150   };
    151 
    152   for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
    153     // Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
    154     // to decoder_peek_si_internal on frames of size < 8.
    155     if (data_sz >= 8) {
    156       vpx_codec_ctx_t dec;
    157       EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
    158       EXPECT_EQ(
    159           (data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
    160           vpx_codec_decode(&dec, data, data_sz, NULL, 0));
    161       vpx_codec_iter_t iter = NULL;
    162       EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
    163       EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
    164     }
    165 
    166     // Verify behavior of vpx_codec_peek_stream_info.
    167     vpx_codec_stream_info_t si;
    168     si.sz = sizeof(si);
    169     EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
    170               vpx_codec_peek_stream_info(codec, data, data_sz, &si));
    171   }
    172 }
    173 #endif  // CONFIG_VP9_DECODER
    174 
    175 TEST(DecodeAPI, HighBitDepthCapability) {
    176 // VP8 should not claim VP9 HBD as a capability.
    177 #if CONFIG_VP8_DECODER
    178   const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo);
    179   EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
    180 #endif
    181 
    182 #if CONFIG_VP9_DECODER
    183   const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo);
    184 #if CONFIG_VP9_HIGHBITDEPTH
    185   EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
    186 #else
    187   EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
    188 #endif
    189 #endif
    190 }
    191 
    192 }  // namespace
    193