Commit 18c08607 authored by Joey Parrish's avatar Joey Parrish
Browse files

Add VPXD_SET_DECRYPTOR support to the VP9 decoder.

Change-Id: I88f86c8ff9af34e0b6531028b691921b54c2fc48
parent dddc3c69
...@@ -317,7 +317,6 @@ CONFIG_LIST=" ...@@ -317,7 +317,6 @@ CONFIG_LIST="
multi_res_encoding multi_res_encoding
temporal_denoising temporal_denoising
experimental experimental
decrypt
${EXPERIMENT_LIST} ${EXPERIMENT_LIST}
" "
CMDLINE_SELECT=" CMDLINE_SELECT="
...@@ -371,7 +370,6 @@ CMDLINE_SELECT=" ...@@ -371,7 +370,6 @@ CMDLINE_SELECT="
multi_res_encoding multi_res_encoding
temporal_denoising temporal_denoising
experimental experimental
decrypt
" "
process_cmdline() { process_cmdline() {
......
...@@ -106,6 +106,7 @@ endif ...@@ -106,6 +106,7 @@ endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9) += convolve_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9) += convolve_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_decrypt_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_test.cc
......
...@@ -94,14 +94,10 @@ TEST(VP8, TestBitIO) { ...@@ -94,14 +94,10 @@ TEST(VP8, TestBitIO) {
vp8_stop_encode(&bw); vp8_stop_encode(&bw);
BOOL_DECODER br; BOOL_DECODER br;
#if CONFIG_DECRYPT encrypt_buffer(bw_buffer, kBufferSize);
encrypt_buffer(bw_buffer, buffer_size); vp8dx_start_decode(&br, bw_buffer, kBufferSize,
vp8dx_start_decode(&br, bw_buffer, buffer_size,
test_decrypt_cb, test_decrypt_cb,
reinterpret_cast<void *>(bw_buffer)); reinterpret_cast<void *>(bw_buffer));
#else
vp8dx_start_decode(&br, bw_buffer, kBufferSize, NULL, NULL);
#endif
bit_rnd.Reset(random_seed); bit_rnd.Reset(random_seed);
for (int i = 0; i < kBitsToTest; ++i) { for (int i = 0; i < kBitsToTest; ++i) {
if (bit_method == 2) { if (bit_method == 2) {
......
...@@ -43,7 +43,7 @@ void test_decrypt_cb(void *decrypt_state, const uint8_t *input, ...@@ -43,7 +43,7 @@ void test_decrypt_cb(void *decrypt_state, const uint8_t *input,
namespace libvpx_test { namespace libvpx_test {
TEST(TestDecrypt, DecryptWorks) { TEST(TestDecrypt, DecryptWorksVp8) {
libvpx_test::IVFVideoSource video("vp80-00-comprehensive-001.ivf"); libvpx_test::IVFVideoSource video("vp80-00-comprehensive-001.ivf");
video.Init(); video.Init();
...@@ -59,14 +59,12 @@ TEST(TestDecrypt, DecryptWorks) { ...@@ -59,14 +59,12 @@ TEST(TestDecrypt, DecryptWorks) {
// decrypt frame // decrypt frame
video.Next(); video.Next();
#if CONFIG_DECRYPT
std::vector<uint8_t> encrypted(video.frame_size()); std::vector<uint8_t> encrypted(video.frame_size());
encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0); encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0);
vp8_decrypt_init di = { test_decrypt_cb, &encrypted[0] }; vpx_decrypt_init di = { test_decrypt_cb, &encrypted[0] };
decoder.Control(VP8D_SET_DECRYPTOR, &di); decoder.Control(VPXD_SET_DECRYPTOR, &di);
#endif // CONFIG_DECRYPT
res = decoder.DecodeFrame(video.cxdata(), video.frame_size()); res = decoder.DecodeFrame(&encrypted[0], encrypted.size());
ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
} }
......
...@@ -70,7 +70,7 @@ TEST(VP9, TestBitIO) { ...@@ -70,7 +70,7 @@ TEST(VP9, TestBitIO) {
GTEST_ASSERT_EQ(bw_buffer[0] & 0x80, 0); GTEST_ASSERT_EQ(bw_buffer[0] & 0x80, 0);
vp9_reader br; vp9_reader br;
vp9_reader_init(&br, bw_buffer, kBufferSize); vp9_reader_init(&br, bw_buffer, kBufferSize, NULL, NULL);
bit_rnd.Reset(random_seed); bit_rnd.Reset(random_seed);
for (int i = 0; i < kBitsToTest; ++i) { for (int i = 0; i < kBitsToTest; ++i) {
if (bit_method == 2) { if (bit_method == 2) {
......
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/ivf_video_source.h"
namespace {
// In a real use the 'decrypt_state' parameter will be a pointer to a struct
// with whatever internal state the decryptor uses. For testing we'll just
// xor with a constant key, and decrypt_state will point to the start of
// the original buffer.
const uint8_t test_key[16] = {
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0
};
void encrypt_buffer(const uint8_t *src, uint8_t *dst, size_t size,
ptrdiff_t offset) {
for (size_t i = 0; i < size; ++i) {
dst[i] = src[i] ^ test_key[(offset + i) & 15];
}
}
void test_decrypt_cb(void *decrypt_state, const uint8_t *input,
uint8_t *output, int count) {
encrypt_buffer(input, output, count,
input - reinterpret_cast<uint8_t *>(decrypt_state));
}
} // namespace
namespace libvpx_test {
TEST(TestDecrypt, DecryptWorksVp9) {
libvpx_test::IVFVideoSource video("vp90-2-05-resize.ivf");
video.Init();
vpx_codec_dec_cfg_t dec_cfg = {0};
VP9Decoder decoder(dec_cfg, 0);
video.Begin();
// no decryption
vpx_codec_err_t res = decoder.DecodeFrame(video.cxdata(), video.frame_size());
ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
// decrypt frame
video.Next();
std::vector<uint8_t> encrypted(video.frame_size());
encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0);
vpx_decrypt_init di = { test_decrypt_cb, &encrypted[0] };
decoder.Control(VPXD_SET_DECRYPTOR, &di);
res = decoder.DecodeFrame(&encrypted[0], encrypted.size());
ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
}
} // namespace libvpx_test
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
extern "C" { extern "C" {
#endif #endif
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
/* Only need this for fixed-size arrays, for structs just assign. */ /* Only need this for fixed-size arrays, for structs just assign. */
#define vp8_copy( Dest, Src) { \ #define vp8_copy( Dest, Src) { \
......
...@@ -10,11 +10,12 @@ ...@@ -10,11 +10,12 @@
#include "dboolhuff.h" #include "dboolhuff.h"
#include "vp8/common/common.h"
int vp8dx_start_decode(BOOL_DECODER *br, int vp8dx_start_decode(BOOL_DECODER *br,
const unsigned char *source, const unsigned char *source,
unsigned int source_sz, unsigned int source_sz,
vp8_decrypt_cb *decrypt_cb, vpx_decrypt_cb decrypt_cb,
void *decrypt_state) void *decrypt_state)
{ {
br->user_buffer_end = source+source_sz; br->user_buffer_end = source+source_sz;
...@@ -39,7 +40,7 @@ void vp8dx_bool_decoder_fill(BOOL_DECODER *br) ...@@ -39,7 +40,7 @@ void vp8dx_bool_decoder_fill(BOOL_DECODER *br)
const unsigned char *bufptr = br->user_buffer; const unsigned char *bufptr = br->user_buffer;
VP8_BD_VALUE value = br->value; VP8_BD_VALUE value = br->value;
int count = br->count; int count = br->count;
int shift = VP8_BD_VALUE_SIZE - 8 - (count + 8); int shift = VP8_BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT);
size_t bytes_left = br->user_buffer_end - bufptr; size_t bytes_left = br->user_buffer_end - bufptr;
size_t bits_left = bytes_left * CHAR_BIT; size_t bits_left = bytes_left * CHAR_BIT;
int x = (int)(shift + CHAR_BIT - bits_left); int x = (int)(shift + CHAR_BIT - bits_left);
...@@ -47,7 +48,7 @@ void vp8dx_bool_decoder_fill(BOOL_DECODER *br) ...@@ -47,7 +48,7 @@ void vp8dx_bool_decoder_fill(BOOL_DECODER *br)
unsigned char decrypted[sizeof(VP8_BD_VALUE) + 1]; unsigned char decrypted[sizeof(VP8_BD_VALUE) + 1];
if (br->decrypt_cb) { if (br->decrypt_cb) {
size_t n = bytes_left > sizeof(decrypted) ? sizeof(decrypted) : bytes_left; size_t n = MIN(sizeof(decrypted), bytes_left);
br->decrypt_cb(br->decrypt_state, bufptr, decrypted, (int)n); br->decrypt_cb(br->decrypt_state, bufptr, decrypted, (int)n);
bufptr = decrypted; bufptr = decrypted;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "vpx_config.h" #include "vpx_config.h"
#include "vpx_ports/mem.h" #include "vpx_ports/mem.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#ifdef __cplusplus #ifdef __cplusplus
...@@ -32,12 +33,6 @@ typedef size_t VP8_BD_VALUE; ...@@ -32,12 +33,6 @@ typedef size_t VP8_BD_VALUE;
Even relatively modest values like 100 would work fine.*/ Even relatively modest values like 100 would work fine.*/
#define VP8_LOTS_OF_BITS (0x40000000) #define VP8_LOTS_OF_BITS (0x40000000)
/*Decrypt n bytes of data from input -> output, using the decrypt_state
passed in VP8D_SET_DECRYPTOR.
*/
typedef void (vp8_decrypt_cb)(void *decrypt_state, const unsigned char *input,
unsigned char *output, int count);
typedef struct typedef struct
{ {
const unsigned char *user_buffer_end; const unsigned char *user_buffer_end;
...@@ -45,7 +40,7 @@ typedef struct ...@@ -45,7 +40,7 @@ typedef struct
VP8_BD_VALUE value; VP8_BD_VALUE value;
int count; int count;
unsigned int range; unsigned int range;
vp8_decrypt_cb *decrypt_cb; vpx_decrypt_cb decrypt_cb;
void *decrypt_state; void *decrypt_state;
} BOOL_DECODER; } BOOL_DECODER;
...@@ -54,7 +49,7 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); ...@@ -54,7 +49,7 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
int vp8dx_start_decode(BOOL_DECODER *br, int vp8dx_start_decode(BOOL_DECODER *br,
const unsigned char *source, const unsigned char *source,
unsigned int source_sz, unsigned int source_sz,
vp8_decrypt_cb *decrypt_cb, vpx_decrypt_cb decrypt_cb,
void *decrypt_state); void *decrypt_state);
void vp8dx_bool_decoder_fill(BOOL_DECODER *br); void vp8dx_bool_decoder_fill(BOOL_DECODER *br);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "vp8/common/reconintra4x4.h" #include "vp8/common/reconintra4x4.h"
#include "vp8/common/reconinter.h" #include "vp8/common/reconinter.h"
#include "detokenize.h" #include "detokenize.h"
#include "vp8/common/common.h"
#include "vp8/common/invtrans.h" #include "vp8/common/invtrans.h"
#include "vp8/common/alloccommon.h" #include "vp8/common/alloccommon.h"
#include "vp8/common/entropymode.h" #include "vp8/common/entropymode.h"
...@@ -1018,8 +1019,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) ...@@ -1018,8 +1019,7 @@ int vp8_decode_frame(VP8D_COMP *pbi)
const unsigned char *clear = data; const unsigned char *clear = data;
if (pbi->decrypt_cb) if (pbi->decrypt_cb)
{ {
int n = (int)(data_end - data); int n = (int)MIN(sizeof(clear_buffer), data_end - data);
if (n > 10) n = 10;
pbi->decrypt_cb(pbi->decrypt_state, data, clear_buffer, n); pbi->decrypt_cb(pbi->decrypt_state, data, clear_buffer, n);
clear = clear_buffer; clear = clear_buffer;
} }
......
...@@ -15,9 +15,7 @@ ...@@ -15,9 +15,7 @@
#include "decodemv.h" #include "decodemv.h"
#include "vpx_mem/vpx_mem.h" #include "vpx_mem/vpx_mem.h"
#include "vp8/common/findnearmv.h" #include "vp8/common/findnearmv.h"
#include "vp8/common/common.h"
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX(x,y) (((x)>(y))?(x):(y))
#define FLOOR(x,q) ((x) & -(1 << (q))) #define FLOOR(x,q) ((x) & -(1 << (q)))
......
...@@ -126,7 +126,7 @@ typedef struct VP8D_COMP ...@@ -126,7 +126,7 @@ typedef struct VP8D_COMP
int independent_partitions; int independent_partitions;
int frame_corrupt_residual; int frame_corrupt_residual;
vp8_decrypt_cb *decrypt_cb; vpx_decrypt_cb decrypt_cb;
void *decrypt_state; void *decrypt_state;
} VP8D_COMP; } VP8D_COMP;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include "vp8/common/findnearmv.h" #include "vp8/common/findnearmv.h"
#include "vp8/common/common.h"
#ifdef VP8_ENTROPY_STATS #ifdef VP8_ENTROPY_STATS
static int mv_ref_ct [31] [4] [2]; static int mv_ref_ct [31] [4] [2];
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "mr_dissim.h" #include "mr_dissim.h"
#include "vpx_mem/vpx_mem.h" #include "vpx_mem/vpx_mem.h"
#include "rdopt.h" #include "rdopt.h"
#include "vp8/common/common.h"
void vp8_cal_low_res_mb_cols(VP8_COMP *cpi) void vp8_cal_low_res_mb_cols(VP8_COMP *cpi)
{ {
......
...@@ -61,9 +61,6 @@ extern "C" { ...@@ -61,9 +61,6 @@ extern "C" {
#define VP8_TEMPORAL_ALT_REF 1 #define VP8_TEMPORAL_ALT_REF 1
#endif #endif
#define MAX(x,y) (((x)>(y))?(x):(y))
#define MIN(x,y) (((x)<(y))?(x):(y))
typedef struct typedef struct
{ {
int kf_indicated; int kf_indicated;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "onyx_int.h" #include "onyx_int.h"
#include "modecosts.h" #include "modecosts.h"
#include "encodeintra.h" #include "encodeintra.h"
#include "vp8/common/common.h"
#include "vp8/common/entropymode.h" #include "vp8/common/entropymode.h"
#include "pickinter.h" #include "pickinter.h"
#include "vp8/common/findnearmv.h" #include "vp8/common/findnearmv.h"
......
...@@ -16,9 +16,10 @@ ...@@ -16,9 +16,10 @@
#include "vpx/vp8dx.h" #include "vpx/vp8dx.h"
#include "vpx/internal/vpx_codec_internal.h" #include "vpx/internal/vpx_codec_internal.h"
#include "vpx_version.h" #include "vpx_version.h"
#include "common/alloccommon.h"
#include "common/common.h"
#include "common/onyxd.h" #include "common/onyxd.h"
#include "decoder/onyxd_int.h" #include "decoder/onyxd_int.h"
#include "common/alloccommon.h"
#include "vpx_mem/vpx_mem.h" #include "vpx_mem/vpx_mem.h"
#if CONFIG_ERROR_CONCEALMENT #if CONFIG_ERROR_CONCEALMENT
#include "decoder/error_concealment.h" #include "decoder/error_concealment.h"
...@@ -56,7 +57,7 @@ struct vpx_codec_alg_priv ...@@ -56,7 +57,7 @@ struct vpx_codec_alg_priv
int dbg_color_b_modes_flag; int dbg_color_b_modes_flag;
int dbg_display_mv_flag; int dbg_display_mv_flag;
#endif #endif
vp8_decrypt_cb *decrypt_cb; vpx_decrypt_cb decrypt_cb;
void *decrypt_state; void *decrypt_state;
vpx_image_t img; vpx_image_t img;
int img_setup; int img_setup;
...@@ -156,7 +157,7 @@ static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t *ctx) ...@@ -156,7 +157,7 @@ static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t *ctx)
static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data, static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data,
unsigned int data_sz, unsigned int data_sz,
vpx_codec_stream_info_t *si, vpx_codec_stream_info_t *si,
vp8_decrypt_cb *decrypt_cb, vpx_decrypt_cb decrypt_cb,
void *decrypt_state) void *decrypt_state)
{ {
vpx_codec_err_t res = VPX_CODEC_OK; vpx_codec_err_t res = VPX_CODEC_OK;
...@@ -177,7 +178,7 @@ static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data, ...@@ -177,7 +178,7 @@ static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data,
const uint8_t *clear = data; const uint8_t *clear = data;
if (decrypt_cb) if (decrypt_cb)
{ {
int n = data_sz > 10 ? 10 : data_sz; int n = MIN(sizeof(clear_buffer), data_sz);
decrypt_cb(decrypt_state, data, clear_buffer, n); decrypt_cb(decrypt_state, data, clear_buffer, n);
clear = clear_buffer; clear = clear_buffer;
} }
...@@ -379,12 +380,15 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, ...@@ -379,12 +380,15 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx,
} }
res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf); res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf);
ctx->yv12_frame_buffers.pbi[0]->decrypt_cb = ctx->decrypt_cb;
ctx->yv12_frame_buffers.pbi[0]->decrypt_state = ctx->decrypt_state;
ctx->decoder_init = 1; ctx->decoder_init = 1;
} }
/* Set these even if already initialized. The caller may have changed the
* decrypt config between frames.
*/
ctx->yv12_frame_buffers.pbi[0]->decrypt_cb = ctx->decrypt_cb;
ctx->yv12_frame_buffers.pbi[0]->decrypt_state = ctx->decrypt_state;
if (!res) if (!res)
{ {
VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0];
...@@ -722,7 +726,7 @@ static vpx_codec_err_t vp8_set_decryptor(vpx_codec_alg_priv_t *ctx, ...@@ -722,7 +726,7 @@ static vpx_codec_err_t vp8_set_decryptor(vpx_codec_alg_priv_t *ctx,
int ctrl_id, int ctrl_id,
va_list args) va_list args)
{ {
vp8_decrypt_init *init = va_arg(args, vp8_decrypt_init *); vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *);
if (init) if (init)
{ {
...@@ -749,7 +753,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = ...@@ -749,7 +753,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
{VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates}, {VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates},
{VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted}, {VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted},
{VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame}, {VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame},
{VP8D_SET_DECRYPTOR, vp8_set_decryptor}, {VPXD_SET_DECRYPTOR, vp8_set_decryptor},
{ -1, NULL}, { -1, NULL},
}; };
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include "vp9/decoder/vp9_reader.h" #include "vp9/decoder/vp9_reader.h"
#include "vp9/decoder/vp9_thread.h" #include "vp9/decoder/vp9_thread.h"
#define MAX_VP9_HEADER_SIZE 80
static int is_compound_reference_allowed(const VP9_COMMON *cm) { static int is_compound_reference_allowed(const VP9_COMMON *cm) {
int i; int i;
for (i = 1; i < REFS_PER_FRAME; ++i) for (i = 1; i < REFS_PER_FRAME; ++i)
...@@ -451,7 +453,9 @@ static void setup_token_decoder(const uint8_t *data, ...@@ -451,7 +453,9 @@ static void setup_token_decoder(const uint8_t *data,
const uint8_t *data_end, const uint8_t *data_end,
size_t read_size, size_t read_size,
struct vpx_internal_error_info *error_info, struct vpx_internal_error_info *error_info,
vp9_reader *r) { vp9_reader *r,
vpx_decrypt_cb decrypt_cb,
void *decrypt_state) {
// Validate the calculated partition length. If the buffer // Validate the calculated partition length. If the buffer
// described by the partition can't be fully read, then restrict // described by the partition can't be fully read, then restrict
// it to the portion that can be (for EC mode) or throw an error. // it to the portion that can be (for EC mode) or throw an error.
...@@ -459,7 +463,7 @@ static void setup_token_decoder(const uint8_t *data, ...@@ -459,7 +463,7 @@ static void setup_token_decoder(const uint8_t *data,
vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt tile length"); "Truncated packet or corrupt tile length");
if (vp9_reader_init(r, data, read_size)) if (vp9_reader_init(r, data, read_size, decrypt_cb, decrypt_state))
vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR, vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR,
"Failed to allocate bool decoder %d", 1); "Failed to allocate bool decoder %d", 1);
} }
...@@ -750,7 +754,9 @@ static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { ...@@ -750,7 +754,9 @@ static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
static size_t get_tile(const uint8_t *const data_end, static size_t get_tile(const uint8_t *const data_end,
int is_last, int is_last,
struct vpx_internal_error_info *error_info, struct vpx_internal_error_info *error_info,
const uint8_t **data) { const uint8_t **data,
vpx_decrypt_cb decrypt_cb,
void *decrypt_state) {
size_t size; size_t size;
if (!is_last) { if (!is_last) {
...@@ -758,7 +764,13 @@ static size_t get_tile(const uint8_t *const data_end, ...@@ -758,7 +764,13 @@ static size_t get_tile(const uint8_t *const data_end,
vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt tile length"); "Truncated packet or corrupt tile length");
size = mem_get_be32(*data); if (decrypt_cb) {
uint8_t be_data[4];
decrypt_cb(decrypt_state, *data, be_data, 4);
size = mem_get_be32(be_data);
} else {
size = mem_get_be32(*data);
}
*data += 4; *data += 4;
if (size > (size_t)(data_end - *data)) if (size > (size_t)(data_end - *data))
...@@ -804,7 +816,8 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi, ...@@ -804,7 +816,8 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,