>From acb4ab5a4f14b7a88ccdf3bdc4b01ddf68fcec29 Mon Sep 17 00:00:00 2001 From: Hazarath Kumar M <hazarathku...@multicorewareinc.com> Date: Wed, 25 Sep 2024 14:35:27 +0530 Subject: [PATCH 4/5] Add Aom film grain characteristics as SEI message to the bitstream
--- doc/reST/cli.rst | 4 + source/common/param.cpp | 7 ++ source/encoder/encoder.cpp | 11 +++ source/encoder/encoder.h | 2 + source/encoder/frameencoder.cpp | 92 ++++++++++++++++++++++ source/encoder/frameencoder.h | 31 ++++++++ source/encoder/sei.h | 131 ++++++++++++++++++++++++++++++++ source/x265.h | 3 + source/x265cli.cpp | 1 + source/x265cli.h | 1 + 10 files changed, 283 insertions(+) diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst index 95cb37f20..a4907f7d2 100755 --- a/doc/reST/cli.rst +++ b/doc/reST/cli.rst @@ -2702,6 +2702,10 @@ Bitstream options Refers to the film grain model characteristics for signal enhancement information transmission. +.. option:: --aom-film-grain <filename> + + Refers to the AOM film grain model characteristics + **CLI_ONLY** DCT Approximations diff --git a/source/common/param.cpp b/source/common/param.cpp index d08bb604e..ceef42589 100755 --- a/source/common/param.cpp +++ b/source/common/param.cpp @@ -402,6 +402,7 @@ void x265_param_default(x265_param* param) #endif /* Film grain characteristics model filename */ param->filmGrain = NULL; + param->aomFilmGrain = NULL; param->bEnableSBRC = 0; /* Multi-View Encoding*/ @@ -1455,6 +1456,7 @@ int x265_param_parse(x265_param* p, const char* name, const char* value) OPT("eos") p->bEnableEndOfSequence = atobool(value); /* Film grain characterstics model filename */ OPT("film-grain") p->filmGrain = (char* )value; + OPT("aom-film-grain") p->aomFilmGrain = (char*)value; OPT("mcstf") p->bEnableTemporalFilter = atobool(value); OPT("sbrc") p->bEnableSBRC = atobool(value); #if ENABLE_ALPHA @@ -2403,6 +2405,8 @@ char *x265_param2string(x265_param* p, int padx, int pady) BOOL(p->bliveVBV2pass, "vbv-live-multi-pass"); if (p->filmGrain) s += sprintf(s, " film-grain=%s", p->filmGrain); // Film grain characteristics model filename + if (p->aomFilmGrain) + s += sprintf(s, " aom-film-grain=%s", p->aomFilmGrain); BOOL(p->bEnableTemporalFilter, "mcstf"); #if ENABLE_ALPHA BOOL(p->bEnableAlpha, "alpha"); @@ -2956,6 +2960,9 @@ void x265_copy_params(x265_param* dst, x265_param* src) /* Film grain */ if (src->filmGrain) dst->filmGrain = src->filmGrain; + /* Aom Film grain*/ + if (src->aomFilmGrain) + dst->aomFilmGrain = src->aomFilmGrain; dst->bEnableSBRC = src->bEnableSBRC; } diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp index 13b98e986..c78413bfb 100644 --- a/source/encoder/encoder.cpp +++ b/source/encoder/encoder.cpp @@ -142,6 +142,7 @@ Encoder::Encoder() m_analysisFileIn = NULL; m_analysisFileOut = NULL; m_filmGrainIn = NULL; + m_aomFilmGrainIn = NULL; m_naluFile = NULL; m_offsetEmergency = NULL; m_iFrameNum = 0; @@ -533,6 +534,14 @@ void Encoder::create() x265_log_file(NULL, X265_LOG_ERROR, "Failed to open film grain characteristics binary file %s\n", m_param->filmGrain); } } + if (m_param->aomFilmGrain) + { + m_aomFilmGrainIn = x265_fopen(m_param->aomFilmGrain, "rb"); + if (!m_aomFilmGrainIn) + { + x265_log_file(NULL, X265_LOG_ERROR, "Failed to open Aom film grain characteristics binary file %s\n", m_param->aomFilmGrain); + } + } m_bZeroLatency = !m_param->bframes && !m_param->lookaheadDepth && m_param->frameNumThreads == 1 && m_param->maxSlices == 1; m_aborted |= parseLambdaFile(m_param); @@ -973,6 +982,8 @@ void Encoder::destroy() fclose(m_naluFile); if (m_filmGrainIn) x265_fclose(m_filmGrainIn); + if (m_aomFilmGrainIn) + x265_fclose(m_aomFilmGrainIn); #ifdef SVT_HEVC X265_FREE(m_svtAppData); diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h index e5020c1dc..4b72f8bf9 100644 --- a/source/encoder/encoder.h +++ b/source/encoder/encoder.h @@ -285,6 +285,8 @@ public: ThreadSafeInteger* zoneWriteCount; /* Film grain model file */ FILE* m_filmGrainIn; + /* Aom film grain model file*/ + FILE* m_aomFilmGrainIn; OrigPicBuffer* m_origPicBuffer; Encoder(); diff --git a/source/encoder/frameencoder.cpp b/source/encoder/frameencoder.cpp index deb478a0f..e21dbfa85 100644 --- a/source/encoder/frameencoder.cpp +++ b/source/encoder/frameencoder.cpp @@ -872,6 +872,14 @@ void FrameEncoder::compressFrame(int layer) readModel(&m_filmGrain, this->m_top->m_filmGrainIn); m_filmGrain.writeSEImessages(m_bs, *slice->m_sps, NAL_UNIT_PREFIX_SEI, m_nalList, m_param->bSingleSeiNal, layer); } + /* Write Aom film grain characteristics if present */ + if (this->m_top->m_aomFilmGrainIn) + { + AomFilmGrainCharacteristics m_aomFilmGrain; + /* Read the Film grain model file */ + readAomModel(&m_aomFilmGrain, this->m_top->m_aomFilmGrainIn); + m_aomFilmGrain.writeSEImessages(m_bs, *slice->m_sps, NAL_UNIT_PREFIX_SEI, m_nalList, m_param->bSingleSeiNal); + } /* Write user SEI */ for (int i = 0; i < m_frame[layer]->m_userSEI.numPayloads; i++) { @@ -2335,6 +2343,90 @@ void FrameEncoder::readModel(FilmGrainCharacteristics* m_filmGrain, FILE* filmgr } } } + +void FrameEncoder::readAomModel(AomFilmGrainCharacteristics* m_aomFilmGrain, FILE* Aomfilmgrain) +{ + char const* errorMessage = "Error reading Aom FilmGrain characteristics\n"; + AomFilmGrain m_afg; + x265_fread((char*)&m_aomFilmGrain->m_apply_grain, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_grain_seed, sizeof(uint16_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_update_grain, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_num_y_points, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + if (m_aomFilmGrain->m_num_y_points) + { + for (int i = 0; i < m_aomFilmGrain->m_num_y_points; i++) + { + for (int j = 0; j < 2; j++) + { + x265_fread((char*)&m_aomFilmGrain->m_scaling_points_y[i][j], sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + } + } + x265_fread((char*)&m_aomFilmGrain->m_num_cb_points, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + if (m_aomFilmGrain->m_num_cb_points) + { + for (int i = 0; i < m_aomFilmGrain->m_num_cb_points; i++) + { + for (int j = 0; j < 2; j++) + { + x265_fread((char*)&m_aomFilmGrain->m_scaling_points_cb[i][j], sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + } + } + x265_fread((char*)&m_aomFilmGrain->m_num_cr_points, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + if (m_aomFilmGrain->m_num_cr_points) + { + for (int i = 0; i < m_aomFilmGrain->m_num_cr_points; i++) + { + for (int j = 0; j < 2; j++) + { + x265_fread((char*)&m_aomFilmGrain->m_scaling_points_cr[i][j], sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + } + } + x265_fread((char*)&m_aomFilmGrain->m_scaling_shift, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_ar_coeff_lag, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + if (m_aomFilmGrain->m_num_y_points) + { + + for (int i = 0; i < 24; i++) + { + x265_fread((char*)&m_aomFilmGrain->m_ar_coeffs_y[i], sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + } + if (m_aomFilmGrain->m_num_cb_points || m_afg.m_chroma_scaling_from_luma) + { + for (int i = 0; i < 25; i++) + { + x265_fread((char*)&m_aomFilmGrain->m_ar_coeffs_cb[i], sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + } + if (m_aomFilmGrain->m_num_cr_points || m_afg.m_chroma_scaling_from_luma) + { + + for (int i = 0; i < 25; i++) + { + x265_fread((char*)&m_aomFilmGrain->m_ar_coeffs_cr[i], sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + } + x265_fread((char*)&m_aomFilmGrain->m_ar_coeff_shift, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_grain_scale_shift, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + if (m_aomFilmGrain->m_num_cb_points) + { + x265_fread((char*)&m_aomFilmGrain->m_cb_mult, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_cb_luma_mult, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_cb_offset, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + if (m_aomFilmGrain->m_num_cr_points) + { + x265_fread((char*)&m_aomFilmGrain->m_cr_mult, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_cr_luma_mult, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_cr_offset, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + } + x265_fread((char*)&m_aomFilmGrain->m_overlap_flag, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); + x265_fread((char*)&m_aomFilmGrain->m_clip_to_restricted_range, sizeof(int32_t), 1, Aomfilmgrain, errorMessage); +} + #if ENABLE_LIBVMAF void FrameEncoder::vmafFrameLevelScore() { diff --git a/source/encoder/frameencoder.h b/source/encoder/frameencoder.h index ebc6e57c5..21d05c2f2 100644 --- a/source/encoder/frameencoder.h +++ b/source/encoder/frameencoder.h @@ -142,6 +142,36 @@ struct FGPresent bool m_presentFlag[3]; }; +struct AomFilmGrain +{ + int32_t m_apply_grain; + int32_t m_update_grain; + int32_t m_scaling_points_y[14][2]; + int32_t m_num_y_points; + int32_t m_scaling_points_cb[10][2]; + int32_t m_num_cb_points; + int32_t m_scaling_points_cr[10][2]; + int32_t m_num_cr_points; + int32_t m_scaling_shift; + int32_t m_ar_coeff_lag; + int32_t m_ar_coeffs_y[24]; + int32_t m_ar_coeffs_cb[25]; + int32_t m_ar_coeffs_cr[25]; + int32_t m_ar_coeff_shift; + int32_t m_cb_mult; + int32_t m_cb_luma_mult; + int32_t m_cb_offset; + int32_t m_cr_mult; + int32_t m_cr_luma_mult; + int32_t m_cr_offset; + int32_t m_overlap_flag; + int32_t m_clip_to_restricted_range; + int32_t m_bitDepth; + int32_t m_chroma_scaling_from_luma; + int32_t m_grain_scale_shift; + uint16_t m_grain_seed; +}; + // Manages the wave-front processing of a single encoding frame class FrameEncoder : public WaveFront, public Thread { @@ -287,6 +317,7 @@ protected: void computeAvgTrainingData(int layer); void collectDynDataRow(CUData& ctu, FrameStats* rowStats); void readModel(FilmGrainCharacteristics* m_filmGrain, FILE* filmgrain); + void readAomModel(AomFilmGrainCharacteristics* m_aomFilmGrain, FILE* Aomfilmgrain); }; } diff --git a/source/encoder/sei.h b/source/encoder/sei.h index e357a1bf5..1fa4dc69b 100644 --- a/source/encoder/sei.h +++ b/source/encoder/sei.h @@ -168,6 +168,137 @@ class FilmGrainCharacteristics : public SEI } }; +class AomFilmGrainCharacteristics : public SEI { + +public: + + AomFilmGrainCharacteristics() + { + m_payloadType = USER_DATA_REGISTERED_ITU_T_T35; + m_payloadSize = 0; + } + + int32_t m_apply_grain; + int32_t m_update_grain; + int32_t m_scaling_points_y[14][2]; + int32_t m_num_y_points; + int32_t m_scaling_points_cb[10][2]; + int32_t m_num_cb_points; + int32_t m_scaling_points_cr[10][2]; + int32_t m_num_cr_points; + int32_t m_scaling_shift; + int32_t m_ar_coeff_lag; + int32_t m_ar_coeffs_y[24]; + int32_t m_ar_coeffs_cb[25]; + int32_t m_ar_coeffs_cr[25]; + int32_t m_ar_coeff_shift; + int32_t m_cb_mult; + int32_t m_cb_luma_mult; + int32_t m_cb_offset; + int32_t m_cr_mult; + int32_t m_cr_luma_mult; + int32_t m_cr_offset; + int32_t m_overlap_flag; + int32_t m_clip_to_restricted_range; + int32_t m_bitDepth; + int32_t m_chroma_scaling_from_luma; + int32_t m_grain_scale_shift; + uint16_t m_grain_seed; + + void writeSEI(const SPS&) + { + WRITE_CODE(0x26, 8, "country_code"); + WRITE_CODE(0x5890, 16, "provider_code"); + WRITE_CODE(0x0001, 16, "provider_oriented_code"); + WRITE_FLAG(m_apply_grain, "afgs1_enable_flag"); + WRITE_CODE(m_grain_seed, 16, "grain_seed"); + WRITE_CODE(0, 3, "film_grain_param_set_idx"); + WRITE_CODE(m_update_grain, 1, "update_grain"); + WRITE_CODE(m_num_y_points, 4, "num_y_points"); + if (m_num_y_points) + { + for (int i = 0; i < m_num_y_points; i++) + { + for (int j = 0; j < 2; j++) + { + WRITE_CODE(m_scaling_points_y[i][j], 8, "scaling_points_y[i][j]"); + } + } + } + WRITE_FLAG(m_num_cb_points == 0 && m_num_cr_points == 0, "luma_only_flag"); + WRITE_FLAG(0, "chroma_scaling_from_luma"); + WRITE_CODE(m_num_cb_points, 4, "num_cb_points"); + if (m_num_cb_points) + { + for (int i = 0; i < m_num_cb_points; i++) + { + for (int j = 0; j < 2; j++) + { + WRITE_CODE(m_scaling_points_cb[i][j], 8, "scaling_points_cb[i][j]"); + } + } + } + WRITE_CODE(m_num_cr_points, 4, "num_cr_points"); + if (m_num_cr_points) + { + for (int i = 0; i < m_num_cr_points; i++) + { + for (int j = 0; j < 2; j++) + { + WRITE_CODE(m_scaling_points_cr[i][j], 8, "scaling_points_cr[i][j]"); + } + } + } + WRITE_CODE(m_scaling_shift - 8, 2, "scaling_shift"); + WRITE_CODE(m_ar_coeff_lag, 2, "ar_coeff_lag"); + if (m_num_y_points) + { + for (int i = 0; i < 24; i++) + { + WRITE_CODE(m_ar_coeffs_y[i] + 128, 8, "ar_coeff_y[i]"); + } + } + if (m_num_cb_points || m_chroma_scaling_from_luma) + { + for (int i = 0; i < 25; i++) + { + WRITE_CODE(m_ar_coeffs_cb[i] + 128, 8, "ar_coeff_cb[i]"); + } + } + if (m_num_cr_points || m_chroma_scaling_from_luma) + { + for (int i = 0; i < 25; i++) + { + WRITE_CODE(m_ar_coeffs_cr[i] + 128, 8, "ar_coeff_cr[i]"); + } + } + WRITE_CODE(m_ar_coeff_shift - 6, 2, "ar_coeff_shift"); + WRITE_CODE(m_grain_scale_shift, 2, "grain_scale_shift"); + if (m_num_cb_points) + { + WRITE_CODE(m_cb_mult, 8, "cb_mult"); + WRITE_CODE(m_cb_luma_mult, 8, "cb_luma_mult"); + WRITE_CODE(m_cb_offset, 9, "cb_offset"); + } + if (m_num_cr_points) + { + WRITE_CODE(m_cr_mult, 8, "cr_mult"); + WRITE_CODE(m_cr_luma_mult, 8, "cr_luma_mult"); + WRITE_CODE(m_cr_offset, 9, "cr_offset"); + } + WRITE_FLAG(m_overlap_flag, "overlap_flag"); + WRITE_FLAG(m_clip_to_restricted_range, "clip_to_restricted_range"); + if (m_bitIf->getNumberOfWrittenBits() % X265_BYTE != 0) + { + WRITE_FLAG(1, "payload_bit_equal_to_one"); + while (m_bitIf->getNumberOfWrittenBits() % X265_BYTE != 0) + { + WRITE_FLAG(0, "payload_bit_equal_to_zero"); + } + } + } +}; + static const uint32_t ISO_IEC_11578_LEN = 16; class SEIuserDataUnregistered : public SEI diff --git a/source/x265.h b/source/x265.h index 532d01b22..54e699317 100644 --- a/source/x265.h +++ b/source/x265.h @@ -2307,6 +2307,9 @@ typedef struct x265_param /* Film Grain Characteristic file */ char* filmGrain; + /* Aom Film Grain Characteristic file */ + char* aomFilmGrain; + /*Motion compensated temporal filter*/ int bEnableTemporalFilter; double temporalFilterStrength; diff --git a/source/x265cli.cpp b/source/x265cli.cpp index ca7d9c973..b9ce96f19 100755 --- a/source/x265cli.cpp +++ b/source/x265cli.cpp @@ -408,6 +408,7 @@ namespace X265_NS { H1(" 4 - encoder abort\n"); H0("\nSEI Message Options\n"); H0(" --film-grain <filename> File containing Film Grain Characteristics to be written as a SEI Message\n"); + H0(" --aom-film-grain <filename> File containing Aom Film Grain Characteristics to be written as a SEI Message\n"); #undef OPT #undef H0 diff --git a/source/x265cli.h b/source/x265cli.h index 2ec48352d..3df0fa7a6 100644 --- a/source/x265cli.h +++ b/source/x265cli.h @@ -395,6 +395,7 @@ static const struct option long_options[] = { "max-vbv-fullness", required_argument, NULL, 0 }, { "scenecut-qp-config", required_argument, NULL, 0 }, { "film-grain", required_argument, NULL, 0 }, + { "aom-film-grain", required_argument, NULL, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, -- 2.36.0.windows.1
0004-Add-Aom-film-grain-characteristics-as-SEI-message-to.patch
Description: Binary data
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel