This patch has been pushed to the master branch. *__________________________* *Karam Singh* *Ph.D. IIT Guwahati* Senior Software (Video Coding) Engineer Mobile: +91 8011279030 Block 9A, 6th floor, DLF Cyber City Manapakkam, Chennai 600 089
On Fri, Sep 27, 2024 at 6:03 PM Anusuya Kumarasamy < anusuya.kumaras...@multicorewareinc.com> wrote: > > > On Fri, Sep 27, 2024 at 3:35 PM Anusuya Kumarasamy < > anusuya.kumaras...@multicorewareinc.com> wrote: > >> 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 >> >> _______________________________________________ > x265-devel mailing list > x265-devel@videolan.org > https://mailman.videolan.org/listinfo/x265-devel >
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel