Implementation for FEC decoder module

This commit is contained in:
dijunkun
2023-11-15 22:01:05 -08:00
parent 31b5d7f2e3
commit b0bee226d1
12 changed files with 940 additions and 484 deletions

127
src/fec/fec_decoder.cpp Normal file
View File

@@ -0,0 +1,127 @@
#include "fec_decoder.h"
#include "log.h"
FecDecoder::FecDecoder() {}
FecDecoder::~FecDecoder() {}
int FecDecoder::Init() {
fec_codec_id_ = OF_CODEC_REED_SOLOMON_GF_2_M_STABLE;
fec_rs_params_ = (of_rs_2_m_parameters_t *)calloc(1, sizeof(*fec_params_));
if (nullptr == fec_rs_params_) {
LOG_ERROR("Create FEC decoder params failed");
return -1;
}
fec_rs_params_->m = 8;
fec_params_ = (of_parameters_t *)fec_rs_params_;
if (OF_STATUS_OK !=
of_create_codec_instance(&fec_session_, fec_codec_id_, OF_DECODER, 2)) {
LOG_ERROR("Create FEC decoder instance failed");
return -1;
}
return 0;
}
int FecDecoder::Release() {
if (!fec_session_) {
LOG_ERROR("Invalid FEC decoder instance");
return -1;
}
{
if (OF_STATUS_OK != of_release_codec_instance(fec_session_)) {
LOG_ERROR("Release FEC decoder instance failed");
return -1;
}
}
if (fec_rs_params_) {
free(fec_rs_params_);
}
return 0;
}
int FecDecoder::ResetParams(unsigned int source_symbol_num) {
if (!fec_session_) {
LOG_ERROR("Invalid FEC decoder instance");
return -1;
}
num_of_received_symbols_ = 0;
num_of_source_packets_ = source_symbol_num;
num_of_total_packets_ =
(unsigned int)floor((double)source_symbol_num / (double)code_rate_);
LOG_ERROR("Set s[{}] r[{}]", num_of_source_packets_,
num_of_total_packets_ - source_symbol_num);
fec_params_->nb_source_symbols = source_symbol_num;
fec_params_->nb_repair_symbols = num_of_total_packets_ - source_symbol_num;
fec_params_->encoding_symbol_length = max_size_of_packet_;
if (OF_STATUS_OK != of_set_fec_parameters(fec_session_, fec_params_)) {
LOG_ERROR("Set FEC params failed for codec_id {}", fec_codec_id_);
return -1;
}
return 0;
}
uint8_t **FecDecoder::DecodeWithNewSymbol(const char *fec_symbol,
unsigned int fec_symbol_id) {
if (!fec_session_) {
LOG_ERROR("Invalid FEC decoder instance");
return nullptr;
}
num_of_received_symbols_++;
if (OF_STATUS_ERROR == of_decode_with_new_symbol(
fec_session_, (char *)fec_symbol, fec_symbol_id)) {
LOG_ERROR("Decode wit new symbol failed");
return nullptr;
}
if ((num_of_received_symbols_ >= fec_params_->nb_source_symbols) &&
(true == of_is_decoding_complete(fec_session_))) {
uint8_t **source_packets =
(uint8_t **)calloc(num_of_total_packets_, sizeof(uint8_t *));
if (!source_packets) {
LOG_ERROR("Calloc failed for source_packets with size [{}])",
num_of_total_packets_);
}
if (OF_STATUS_OK !=
of_get_source_symbols_tab(fec_session_, (void **)source_packets)) {
LOG_ERROR("Get source symbols failed");
return nullptr;
}
return source_packets;
}
return nullptr;
}
int FecDecoder::ReleaseSourcePackets(uint8_t **source_packets) {
if (nullptr == source_packets) {
LOG_ERROR(
"Release source packets failed, due to source_packets is nullptr");
return -1;
}
// for (unsigned int index = 0; index < num_of_source_packets_; index++) {
// if (source_packets[index]) {
// LOG_ERROR("Free [{}]", index);
// free(source_packets[index]);
// }
// }
free(source_packets);
return 0;
}

50
src/fec/fec_decoder.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* @Author: DI JUNKUN
* @Date: 2023-11-15
* Copyright (c) 2023 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _FEC_DECODER_H_
#define _FEC_DECODER_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "lib_common/of_openfec_api.h"
#ifdef __cplusplus
};
#endif
class FecDecoder {
public:
FecDecoder();
~FecDecoder();
public:
int Init();
int Release();
int ResetParams(unsigned int source_symbol_num);
uint8_t **DecodeWithNewSymbol(const char *fec_symbol,
unsigned int fec_symbol_id);
int ReleaseSourcePackets(uint8_t **source_packets);
private:
double code_rate_ = 0.667;
int max_size_of_packet_ = 1400;
private:
of_codec_id_t fec_codec_id_ = OF_CODEC_REED_SOLOMON_GF_2_M_STABLE;
of_session_t *fec_session_ = nullptr;
of_parameters_t *fec_params_ = nullptr;
of_rs_2_m_parameters_t *fec_rs_params_ = nullptr;
of_ldpc_parameters_t *fec_ldpc_params_ = nullptr;
unsigned int num_of_received_symbols_ = 0;
unsigned int num_of_source_packets_ = 0;
unsigned int num_of_total_packets_ = 0;
};
#endif

View File

@@ -40,6 +40,10 @@ int FecEncoder::Release() {
}
}
if (fec_rs_params_) {
free(fec_rs_params_);
}
return 0;
}