Commit eb895ef5 authored by Neil Birkbeck's avatar Neil Birkbeck

Add film grain table input to allow injecting grain params.

In typical scenario where film grain renoising is done, the denoiser
will be applied to the input and the denoised source will be encoded.
This film grain table is meant to map a timestamp to corresponding
noise parameters, and can be provided along with the denoised source.

In an online denoising (within the encoder) the table can be used
to enqueue film grain parameters that can then be dereference when
the encoded frames are written out.

Change-Id: Iaec82a6df2c73da31d75c04d08fdf210607f1ba8
parent 4352fed3
......@@ -796,6 +796,10 @@ enum aome_enc_control_id {
* 1..16 = different test vectors for grain
*/
AV1E_SET_FILM_GRAIN_TEST_VECTOR,
/*!\brief Codec control function to set the path to the film grain parameters
*/
AV1E_SET_FILM_GRAIN_TABLE,
};
/*!\brief aom 1-D scaling mode
......@@ -1085,6 +1089,9 @@ AOM_CTRL_USE_TYPE(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int)
AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TEST_VECTOR, unsigned int)
#define AOM_CTRL_AV1E_SET_FILM_GRAIN_TEST_VECTOR
AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TABLE, const char *)
#define AOM_CTRL_AV1E_SET_FILM_GRAIN_TABLE
AOM_CTRL_USE_TYPE(AV1E_SET_CDF_UPDATE_MODE, int)
#define AOM_CTRL_AV1E_SET_CDF_UPDATE_MODE
......
......@@ -218,6 +218,8 @@ if (CONFIG_AV1_ENCODER)
"${AOM_ROOT}/aom_dsp/bitwriter.h"
"${AOM_ROOT}/aom_dsp/bitwriter_buffer.c"
"${AOM_ROOT}/aom_dsp/bitwriter_buffer.h"
"${AOM_ROOT}/aom_dsp/grain_table.c"
"${AOM_ROOT}/aom_dsp/grain_table.h"
"${AOM_ROOT}/aom_dsp/noise_util.h"
"${AOM_ROOT}/aom_dsp/noise_util.c"
"${AOM_ROOT}/aom_dsp/noise_model.c"
......
This diff is collapsed.
/*
* Copyright (c) 2018, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
/*!\file
* \brief A table mapping from time to corresponding film grain parameters.
*
* In order to apply grain synthesis in the decoder, the film grain parameters
* need to be signalled in the encoder. The film grain parameters are time
* varying, and for two-pass encoding (and denoiser implementation flexibility)
* it is common to denoise the video and do parameter estimation before encoding
* the denoised video.
*
* The film grain table is used to provide this flexibility and is used as a
* parameter that is passed to the encoder.
*
* Further, if regraining is to be done in say a single pass mode, or in two
* pass within the encoder (before frames are added to the lookahead buffer),
* this data structure can be used to keep track of on-the-fly estimated grain
* parameters, that are then extracted from the table before the encoded frame
* is written.
*/
#ifndef AOM_AOM_DSP_GRAIN_TABLE_H_
#define AOM_AOM_DSP_GRAIN_TABLE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "aom_dsp/grain_synthesis.h"
#include "aom/internal/aom_codec_internal.h"
typedef struct aom_film_grain_table_entry_t {
aom_film_grain_t params;
int64_t start_time;
int64_t end_time;
struct aom_film_grain_table_entry_t *next;
} aom_film_grain_table_entry_t;
typedef struct {
aom_film_grain_table_entry_t *head;
aom_film_grain_table_entry_t *tail;
} aom_film_grain_table_t;
/*!\brief Add a mapping from [time_stamp, end_time) to the given grain
* parameters
*
* \param[in/out] table The grain table
* \param[in] time_stamp The start time stamp
* \param[in] end_stamp The end time_stamp
* \param[in] grain The grain parameters
*/
void aom_film_grain_table_append(aom_film_grain_table_t *table,
int64_t time_stamp, int64_t end_time,
const aom_film_grain_t *grain);
/*!\brief Look-up (and optionally erase) the grain parameters for the given time
*
* \param[in] table The grain table
* \param[in] time_stamp The start time stamp
* \param[in] end_stamp The end time_stamp
* \param[in] erase Whether the time segment can be deleted
* \param[out] grain The output grain parameters
*/
int aom_film_grain_table_lookup(aom_film_grain_table_t *t, int64_t time_stamp,
int64_t end_time, int erase,
aom_film_grain_t *grain);
/*!\brief Reads the grain table from a file.
*
* \param[out] table The grain table
* \param[in] filename The file to read from
* \param[in] error_info Error info for tracking errors
*/
aom_codec_err_t aom_film_grain_table_read(
aom_film_grain_table_t *table, const char *filename,
struct aom_internal_error_info *error_info);
/*!\brief Writes the grain table from a file.
*
* \param[out] table The grain table
* \param[in] filename The file to read from
* \param[in] error_info Error info for tracking errors
*/
aom_codec_err_t aom_film_grain_table_write(
const aom_film_grain_table_t *t, const char *filename,
struct aom_internal_error_info *error_info);
void aom_film_grain_table_free(aom_film_grain_table_t *t);
#ifdef __cplusplus
}
#endif
#endif
......@@ -473,6 +473,9 @@ static const arg_def_t film_grain_test =
ARG_DEF(NULL, "film-grain-test", 1,
"Film grain test vectors (0: none (default), 1: test-1 2: test-2, "
"... 16: test-16)");
static const arg_def_t film_grain_table =
ARG_DEF(NULL, "film-grain-table", 1,
"Path to file containing film grain parameters");
#endif
static const arg_def_t disable_tempmv = ARG_DEF(
NULL, "disable-tempmv", 1, "Disable temporal mv prediction (default is 0)");
......@@ -663,6 +666,7 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
&timing_info,
#if CONFIG_FILM_GRAIN
&film_grain_test,
&film_grain_table,
#endif
&disable_tempmv,
&bitdeptharg,
......@@ -717,6 +721,7 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
AV1E_SET_TIMING_INFO,
#if CONFIG_FILM_GRAIN
AV1E_SET_FILM_GRAIN_TEST_VECTOR,
AV1E_SET_FILM_GRAIN_TABLE,
#endif
AV1E_SET_DISABLE_TEMPMV,
AV1E_SET_ENABLE_DF,
......@@ -796,6 +801,7 @@ struct stream_config {
int arg_ctrls[ARG_CTRL_CNT_MAX][2];
int arg_ctrl_cnt;
int write_webm;
const char *film_grain_filename;
#if CONFIG_OBU_NO_IVF
int write_ivf;
#endif
......@@ -1071,6 +1077,11 @@ static struct stream_state *new_stream(struct AvxEncoderConfig *global,
static void set_config_arg_ctrls(struct stream_config *config, int key,
const struct arg *arg) {
int j;
if (key == AV1E_SET_FILM_GRAIN_TABLE) {
config->film_grain_filename = arg->val;
return;
}
/* Point either to the next free element or the first instance of this
* control.
*/
......@@ -1559,6 +1570,10 @@ static void initialize_encoder(struct stream_state *stream,
ctx_exit_on_error(&stream->encoder, "Failed to control codec");
}
if (stream->config.film_grain_filename) {
aom_codec_control_(&stream->encoder, AV1E_SET_FILM_GRAIN_TABLE,
stream->config.film_grain_filename);
}
#if CONFIG_AV1_DECODER
if (global->test_decode != TEST_DECODE_OFF) {
......
......@@ -89,6 +89,7 @@ struct av1_extracfg {
#if CONFIG_FILM_GRAIN
int film_grain_test_vector;
const char *film_grain_table_filename;
#endif
unsigned int motion_vector_unit_test;
#if CONFIG_CDF_UPDATE_MODE
......@@ -156,7 +157,8 @@ static struct av1_extracfg default_extra_cfg = {
0, // Single tile decoding is off by default.
#if CONFIG_FILM_GRAIN
0,
0, // film_grain_test_vector
0, // film_grain_table_filename
#endif
0, // motion_vector_unit_test
#if CONFIG_CDF_UPDATE_MODE
......@@ -624,6 +626,7 @@ static aom_codec_err_t set_encoder_config(
#if CONFIG_FILM_GRAIN
oxcf->film_grain_test_vector = extra_cfg->film_grain_test_vector;
oxcf->film_grain_table_filename = extra_cfg->film_grain_table_filename;
#endif
oxcf->large_scale_tile = cfg->large_scale_tile;
oxcf->single_tile_decoding =
......@@ -1006,6 +1009,13 @@ static aom_codec_err_t ctrl_set_film_grain_test_vector(
CAST(AV1E_SET_FILM_GRAIN_TEST_VECTOR, args);
return update_extra_cfg(ctx, &extra_cfg);
}
static aom_codec_err_t ctrl_set_film_grain_table(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.film_grain_table_filename = CAST(AV1E_SET_FILM_GRAIN_TABLE, args);
return update_extra_cfg(ctx, &extra_cfg);
}
#endif
#if CONFIG_EXT_DELTA_Q
......@@ -1641,6 +1651,7 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AV1E_SET_SINGLE_TILE_DECODING, ctrl_set_single_tile_decoding },
#if CONFIG_FILM_GRAIN
{ AV1E_SET_FILM_GRAIN_TEST_VECTOR, ctrl_set_film_grain_test_vector },
{ AV1E_SET_FILM_GRAIN_TABLE, ctrl_set_film_grain_table },
#endif // CONFIG_FILM_GRAIN
{ AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
......
......@@ -33,6 +33,7 @@
#endif
#if CONFIG_FILM_GRAIN
#include "aom_dsp/grain_synthesis.h"
#include "aom_dsp/grain_table.h"
#endif
#ifdef __cplusplus
extern "C" {
......@@ -518,6 +519,7 @@ typedef struct AV1Common {
int above_context_alloc_cols;
WarpedMotionParams global_motion[TOTAL_REFS_PER_FRAME];
#if CONFIG_FILM_GRAIN
aom_film_grain_table_t *film_grain_table;
int film_grain_params_present;
aom_film_grain_t film_grain_params;
#endif
......
......@@ -458,6 +458,12 @@ static void update_film_grain_parameters(struct AV1_COMP *cpi,
AV1_COMMON *const cm = &cpi->common;
cpi->oxcf = *oxcf;
if (cm->film_grain_table) {
aom_film_grain_table_free(cm->film_grain_table);
aom_free(cm->film_grain_table);
}
cm->film_grain_table = 0;
if (oxcf->film_grain_test_vector) {
cm->film_grain_params_present = 1;
if (cm->frame_type == KEY_FRAME) {
......@@ -470,6 +476,12 @@ static void update_film_grain_parameters(struct AV1_COMP *cpi,
cm->film_grain_params.clip_to_restricted_range = 0;
}
}
} else if (oxcf->film_grain_table_filename) {
cm->film_grain_table = aom_malloc(sizeof(*cm->film_grain_table));
memset(cm->film_grain_table, 0, sizeof(aom_film_grain_table_t));
aom_film_grain_table_read(cm->film_grain_table,
oxcf->film_grain_table_filename, &cm->error);
} else {
cm->film_grain_params_present = 0;
memset(&cm->film_grain_params, 0, sizeof(cm->film_grain_params));
......@@ -5832,7 +5844,13 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
cm->cur_frame->buf.buf_8bit_valid = 0;
#if CONFIG_FILM_GRAIN
if (cm->film_grain_table) {
cm->film_grain_params_present = aom_film_grain_table_lookup(
cm->film_grain_table, *time_stamp, *time_end, 0 /* erase */,
&cm->film_grain_params);
}
cm->cur_frame->film_grain_params_present = cm->film_grain_params_present;
#endif
......
......@@ -282,6 +282,7 @@ typedef struct AV1EncoderConfig {
uint32_t num_ticks_per_picture;
#if CONFIG_FILM_GRAIN
int film_grain_test_vector;
const char *film_grain_table_filename;
#endif
#if CONFIG_CDF_UPDATE_MODE
......
#include <string>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "aom_dsp/grain_table.h"
#include "aom/internal/aom_codec_internal.h"
#include "av1/encoder/grain_test_vectors.h"
#include "test/video_source.h"
void grain_equal(const aom_film_grain_t *expected,
const aom_film_grain_t *actual) {
EXPECT_EQ(expected->apply_grain, actual->apply_grain);
EXPECT_EQ(expected->update_parameters, actual->update_parameters);
if (!expected->update_parameters) return;
EXPECT_EQ(expected->num_y_points, actual->num_y_points);
EXPECT_EQ(expected->num_cb_points, actual->num_cb_points);
EXPECT_EQ(expected->num_cr_points, actual->num_cr_points);
EXPECT_EQ(0, memcmp(expected->scaling_points_y, actual->scaling_points_y,
expected->num_y_points *
sizeof(expected->scaling_points_y[0])));
EXPECT_EQ(0, memcmp(expected->scaling_points_cb, actual->scaling_points_cb,
expected->num_cb_points *
sizeof(expected->scaling_points_cb[0])));
EXPECT_EQ(0, memcmp(expected->scaling_points_cr, actual->scaling_points_cr,
expected->num_cr_points *
sizeof(expected->scaling_points_cr[0])));
EXPECT_EQ(expected->scaling_shift, actual->scaling_shift);
EXPECT_EQ(expected->ar_coeff_lag, actual->ar_coeff_lag);
EXPECT_EQ(expected->ar_coeff_shift, actual->ar_coeff_shift);
const int num_pos_luma =
2 * expected->ar_coeff_lag * (expected->ar_coeff_lag + 1);
const int num_pos_chroma = num_pos_luma;
EXPECT_EQ(0, memcmp(expected->ar_coeffs_y, actual->ar_coeffs_y,
sizeof(expected->ar_coeffs_y[0]) * num_pos_luma));
if (actual->num_cb_points || actual->chroma_scaling_from_luma) {
EXPECT_EQ(0, memcmp(expected->ar_coeffs_cb, actual->ar_coeffs_cb,
sizeof(expected->ar_coeffs_cb[0]) * num_pos_chroma));
}
if (actual->num_cr_points || actual->chroma_scaling_from_luma) {
EXPECT_EQ(0, memcmp(expected->ar_coeffs_cr, actual->ar_coeffs_cr,
sizeof(expected->ar_coeffs_cr[0]) * num_pos_chroma));
}
EXPECT_EQ(expected->overlap_flag, actual->overlap_flag);
EXPECT_EQ(expected->chroma_scaling_from_luma,
actual->chroma_scaling_from_luma);
EXPECT_EQ(expected->grain_scale_shift, actual->grain_scale_shift);
// EXPECT_EQ(expected->random_seed, actual->random_seed);
// clip_to_restricted and bit_depth aren't written
if (expected->num_cb_points) {
EXPECT_EQ(expected->cb_mult, actual->cb_mult);
EXPECT_EQ(expected->cb_luma_mult, actual->cb_luma_mult);
EXPECT_EQ(expected->cb_offset, actual->cb_offset);
}
if (expected->num_cr_points) {
EXPECT_EQ(expected->cr_mult, actual->cr_mult);
EXPECT_EQ(expected->cr_luma_mult, actual->cr_luma_mult);
EXPECT_EQ(expected->cr_offset, actual->cr_offset);
}
}
TEST(FilmGrainTableTest, AddAndLookupSingleSegment) {
aom_film_grain_table_t table;
memset(&table, 0, sizeof(table));
aom_film_grain_t grain;
EXPECT_FALSE(aom_film_grain_table_lookup(&table, 0, 1000, false, &grain));
aom_film_grain_table_append(&table, 1000, 2000, film_grain_test_vectors + 0);
EXPECT_FALSE(aom_film_grain_table_lookup(&table, 0, 1000, false, &grain));
EXPECT_FALSE(aom_film_grain_table_lookup(&table, 2000, 3000, false, &grain));
EXPECT_TRUE(aom_film_grain_table_lookup(&table, 1000, 2000, false, &grain));
grain.bit_depth = film_grain_test_vectors[0].bit_depth;
EXPECT_EQ(0, memcmp(&grain, film_grain_test_vectors + 0, sizeof(table)));
// Extend the existing segment
aom_film_grain_table_append(&table, 2000, 3000, film_grain_test_vectors + 0);
EXPECT_EQ(0, table.head->next);
// Lookup and remove and check that the entry is no longer there
EXPECT_TRUE(aom_film_grain_table_lookup(&table, 1000, 2000, true, &grain));
EXPECT_FALSE(aom_film_grain_table_lookup(&table, 1000, 2000, false, &grain));
EXPECT_TRUE(aom_film_grain_table_lookup(&table, 2000, 3000, true, &grain));
EXPECT_FALSE(aom_film_grain_table_lookup(&table, 2000, 3000, false, &grain));
EXPECT_EQ(0, table.head);
EXPECT_EQ(0, table.tail);
aom_film_grain_table_free(&table);
}
TEST(FilmGrainTableTest, SplitSingleSegment) {
aom_film_grain_table_t table;
aom_film_grain_t grain;
memset(&table, 0, sizeof(table));
aom_film_grain_table_append(&table, 0, 1000, film_grain_test_vectors + 0);
// Test lookup and remove that adjusts start time
EXPECT_TRUE(aom_film_grain_table_lookup(&table, 0, 100, true, &grain));
EXPECT_EQ(NULL, table.head->next);
EXPECT_EQ(100, table.head->start_time);
// Test lookup and remove that adjusts end time
EXPECT_TRUE(aom_film_grain_table_lookup(&table, 900, 1000, true, &grain));
EXPECT_EQ(NULL, table.head->next);
EXPECT_EQ(100, table.head->start_time);
EXPECT_EQ(900, table.head->end_time);
// Test lookup and remove that splits the first entry
EXPECT_TRUE(aom_film_grain_table_lookup(&table, 400, 600, true, &grain));
EXPECT_EQ(100, table.head->start_time);
EXPECT_EQ(400, table.head->end_time);
ASSERT_NE((void *)NULL, table.head->next);
EXPECT_EQ(table.tail, table.head->next);
EXPECT_EQ(600, table.head->next->start_time);
EXPECT_EQ(900, table.head->next->end_time);
aom_film_grain_table_free(&table);
}
TEST(FilmGrainTableTest, AddAndLookupMultipleSegments) {
aom_film_grain_table_t table;
memset(&table, 0, sizeof(table));
aom_film_grain_t grain;
const int kNumTestVectors =
sizeof(film_grain_test_vectors) / sizeof(film_grain_test_vectors[0]);
for (int i = 0; i < kNumTestVectors; ++i) {
aom_film_grain_table_append(&table, i * 1000, (i + 1) * 1000,
film_grain_test_vectors + i);
}
for (int i = kNumTestVectors - 1; i >= 0; --i) {
EXPECT_TRUE(aom_film_grain_table_lookup(&table, i * 1000, (i + 1) * 1000,
true, &grain));
grain_equal(film_grain_test_vectors + i, &grain);
EXPECT_FALSE(aom_film_grain_table_lookup(&table, i * 1000, (i + 1) * 1000,
true, &grain));
}
// Verify that all the data has been removed
for (int i = 0; i < kNumTestVectors; ++i) {
EXPECT_FALSE(aom_film_grain_table_lookup(&table, i * 1000, (i + 1) * 1000,
true, &grain));
}
aom_film_grain_table_free(&table);
}
class FilmGrainTableIOTest : public ::testing::Test {
protected:
void SetUp() { memset(&error_, 0, sizeof(error_)); }
struct aom_internal_error_info error_;
};
TEST_F(FilmGrainTableIOTest, ReadMissingFile) {
aom_film_grain_table_t table;
memset(&table, 0, sizeof(table));
ASSERT_EQ(AOM_CODEC_ERROR, aom_film_grain_table_read(
&table, "/path/to/missing/file", &error_));
}
TEST_F(FilmGrainTableIOTest, ReadTruncatedFile) {
aom_film_grain_table_t table;
memset(&table, 0, sizeof(table));
std::string grain_file;
FILE *file = libaom_test::GetTempOutFile(&grain_file);
fwrite("deadbeef", 8, 1, file);
fclose(file);
ASSERT_EQ(AOM_CODEC_ERROR,
aom_film_grain_table_read(&table, grain_file.c_str(), &error_));
EXPECT_EQ(0, remove(grain_file.c_str()));
}
TEST_F(FilmGrainTableIOTest, RoundTripReadWrite) {
aom_film_grain_table_t table;
memset(&table, 0, sizeof(table));
aom_film_grain_t expected_grain[16];
const int kNumTestVectors =
sizeof(film_grain_test_vectors) / sizeof(film_grain_test_vectors[0]);
for (int i = 0; i < kNumTestVectors; ++i) {
expected_grain[i] = film_grain_test_vectors[i];
expected_grain[i].random_seed = i;
expected_grain[i].update_parameters = i % 2;
expected_grain[i].apply_grain = (i + 1) % 2;
expected_grain[i].bit_depth = 0;
aom_film_grain_table_append(&table, i * 1000, (i + 1) * 1000,
expected_grain + i);
}
std::string grain_file;
fclose(libaom_test::GetTempOutFile(&grain_file));
ASSERT_EQ(AOM_CODEC_OK,
aom_film_grain_table_write(&table, grain_file.c_str(), &error_));
aom_film_grain_table_free(&table);
memset(&table, 0, sizeof(table));
ASSERT_EQ(AOM_CODEC_OK,
aom_film_grain_table_read(&table, grain_file.c_str(), &error_));
for (int i = 0; i < kNumTestVectors; ++i) {
aom_film_grain_t grain;
EXPECT_TRUE(aom_film_grain_table_lookup(&table, i * 1000, (i + 1) * 1000,
true, &grain));
grain_equal(expected_grain + i, &grain);
}
aom_film_grain_table_free(&table);
EXPECT_EQ(0, remove(grain_file.c_str()));
}
TEST_F(FilmGrainTableIOTest, RoundTripSplit) {
std::string grain_file;
fclose(libaom_test::GetTempOutFile(&grain_file));
aom_film_grain_table_t table;
memset(&table, 0, sizeof(table));
aom_film_grain_t grain = film_grain_test_vectors[0];
aom_film_grain_table_append(&table, 0, 3000, &grain);
ASSERT_TRUE(aom_film_grain_table_lookup(&table, 1000, 2000, true, &grain));
ASSERT_TRUE(aom_film_grain_table_lookup(&table, 0, 1000, false, &grain));
EXPECT_FALSE(aom_film_grain_table_lookup(&table, 1000, 2000, false, &grain));
ASSERT_TRUE(aom_film_grain_table_lookup(&table, 2000, 3000, false, &grain));
ASSERT_EQ(AOM_CODEC_OK,
aom_film_grain_table_write(&table, grain_file.c_str(), &error_));
aom_film_grain_table_free(&table);
memset(&table, 0, sizeof(table));
ASSERT_EQ(AOM_CODEC_OK,
aom_film_grain_table_read(&table, grain_file.c_str(), &error_));
ASSERT_TRUE(aom_film_grain_table_lookup(&table, 0, 1000, false, &grain));
ASSERT_FALSE(aom_film_grain_table_lookup(&table, 1000, 2000, false, &grain));
ASSERT_TRUE(aom_film_grain_table_lookup(&table, 2000, 3000, false, &grain));
aom_film_grain_table_free(&table);
EXPECT_EQ(0, remove(grain_file.c_str()));
}
......@@ -270,6 +270,7 @@ if (NOT BUILD_SHARED_LIBS)
${AOM_UNIT_TEST_COMMON_SOURCES}
"${AOM_ROOT}/test/divu_small_test.cc"
"${AOM_ROOT}/test/ethread_test.cc"
"${AOM_ROOT}/test/film_grain_table_test.cc"
"${AOM_ROOT}/test/coding_path_sync.cc"
"${AOM_ROOT}/test/idct8x8_test.cc"
"${AOM_ROOT}/test/superframe_test.cc"
......
......@@ -71,7 +71,10 @@ static FILE *GetTempOutFile(std::string *file_name) {
}
return NULL;
#else
return tmpfile();
char name_template[] = "/tmp/libaomtest.XXXXXX";
const int fd = mkstemp(name_template);
*file_name = name_template;
return fdopen(fd, "wb+");
#endif
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment