Opus codec module test pass

This commit is contained in:
dijunkun
2023-11-29 19:16:12 -08:00
parent d79720532d
commit 3a1be00ca5
41 changed files with 1243 additions and 177 deletions

View File

@@ -0,0 +1,66 @@
#include "audio_decoder.h"
#include "log.h"
#define MAX_FRAME_SIZE 6 * 960
#define CHANNELS 1
unsigned char pcm_bytes[MAX_FRAME_SIZE * CHANNELS * 2];
opus_int16 out_data[MAX_FRAME_SIZE * CHANNELS];
AudioDecoder::AudioDecoder(int sample_rate, int channel_num, int frame_size)
: sample_rate_(sample_rate),
channel_num_(channel_num),
frame_size_(frame_size) {}
AudioDecoder::~AudioDecoder() {
if (opus_decoder_) {
opus_decoder_destroy(opus_decoder_);
}
}
int AudioDecoder::Init() {
int err;
opus_decoder_ = opus_decoder_create(sample_rate_, channel_num_, &err);
opus_decoder_ctl(opus_decoder_, OPUS_SET_LSB_DEPTH(16));
// opus_decoder_ctl(opus_decoder_, OPUS_SET_INBAND_FEC(1));
if (err < 0 || opus_decoder_ == NULL) {
LOG_ERROR("Create opus opus_decoder_ failed");
return -1;
}
// pcm_file = fopen("decode.pcm", "wb+");
// pcm_file1 = fopen("decode1.pcm", "wb+");
return 0;
}
int AudioDecoder::Decode(
const uint8_t* data, int size,
std::function<void(uint8_t*, int)> on_receive_decoded_frame) {
// LOG_ERROR("input opus size = {}", size);
auto frame_size =
opus_decode(opus_decoder_, data, size, out_data, MAX_FRAME_SIZE, 0);
if (frame_size < 0) {
LOG_ERROR("Decode opus frame failed");
return -1;
}
// LOG_ERROR("frame_size = {}", frame_size);
// for (auto i = 0; i < channel_num_ * frame_size; i++) {
// pcm_bytes[2 * i] = out_data[i] & 0xFF;
// pcm_bytes[2 * i + 1] = (out_data[i] >> 8) & 0xFF;
// }
// fwrite(pcm_bytes, sizeof(short), frame_size * channel_num_, pcm_file);
// fflush(pcm_file);
if (on_receive_decoded_frame) {
on_receive_decoded_frame((uint8_t*)out_data,
frame_size * channel_num_ * sizeof(opus_int16));
}
return 0;
}

View File

@@ -0,0 +1,42 @@
/*
* @Author: DI JUNKUN
* @Date: 2023-11-24
* Copyright (c) 2023 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _AUDIO_DECODER_H_
#define _AUDIO_DECODER_H_
#include <stdio.h>
#include <functional>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
#include "audio_frame.h"
#include "opus/opus.h"
class AudioDecoder {
public:
AudioDecoder(int sample_rate, int channel_num, int frame_size);
~AudioDecoder();
public:
int Init();
int Decode(const uint8_t *data, int size,
std::function<void(uint8_t *, int)> on_receive_decoded_frame);
private:
/* data */
OpusDecoder *opus_decoder_ = nullptr;
int sample_rate_ = 48000;
int channel_num_ = 1;
int frame_size_ = 0;
FILE *pcm_file;
FILE *pcm_file1;
};
#endif

View File

@@ -0,0 +1,93 @@
#include "audio_encoder.h"
#include <stdlib.h>
#include <chrono>
#include <cstring>
#include "log.h"
#define MAX_PACKET_SIZE 4000
unsigned char output_data[MAX_PACKET_SIZE] = {0};
static uint32_t last_ts = 0;
static unsigned char out_data[MAX_PACKET_SIZE] = {0};
AudioEncoder::AudioEncoder(int sample_rate, int channel_num, int frame_size)
: sample_rate_(sample_rate),
channel_num_(channel_num),
frame_size_(frame_size) {}
AudioEncoder::~AudioEncoder() {
if (opus_encoder_) {
opus_encoder_destroy(opus_encoder_);
}
}
int AudioEncoder::Init() {
last_ts = static_cast<uint32_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch())
.count());
int err;
int applications[3] = {OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_VOIP,
OPUS_APPLICATION_RESTRICTED_LOWDELAY};
opus_encoder_ = opus_encoder_create(sample_rate_, channel_num_,
OPUS_APPLICATION_VOIP, &err);
if (err != OPUS_OK || opus_encoder_ == NULL) {
LOG_ERROR("Create opus encoder failed");
}
// opus_encoder_ctl(opus_encoder_, OPUS_SET_VBR(0));
// opus_encoder_ctl(opus_encoder_, OPUS_SET_VBR_CONSTRAINT(true));
// opus_encoder_ctl(opus_encoder_,
// OPUS_SET_BITRATE(sample_rate_ * channel_num_));
// opus_encoder_ctl(opus_encoder_, OPUS_SET_COMPLEXITY(0));
// opus_encoder_ctl(opus_encoder_, OPUS_SET_SIGNAL(OPUS_APPLICATION_VOIP));
opus_encoder_ctl(opus_encoder_, OPUS_SET_LSB_DEPTH(16));
// opus_encoder_ctl(opus_encoder_, OPUS_SET_DTX(0));
// opus_encoder_ctl(opus_encoder_, OPUS_SET_INBAND_FEC(1));
opus_encoder_ctl(opus_encoder_,
OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_10_MS));
return 0;
}
int AudioEncoder::Encode(
const uint8_t *data, int size,
std::function<int(char *encoded_audio_buffer, size_t size)>
on_encoded_audio_buffer) {
if (!on_encoded_audio_buffer_) {
on_encoded_audio_buffer_ = on_encoded_audio_buffer;
}
// uint32_t now_ts = static_cast<uint32_t>(
// std::chrono::duration_cast<std::chrono::milliseconds>(
// std::chrono::high_resolution_clock::now().time_since_epoch())
// .count());
// printf("1 Time cost: %d size: %d\n", now_ts - last_ts, size);
// last_ts = now_ts;
auto ret = opus_encode(opus_encoder_, (opus_int16 *)data, size, out_data,
MAX_PACKET_SIZE);
if (ret < 0) {
printf("opus decode failed, %d\n", ret);
return -1;
}
if (on_encoded_audio_buffer_) {
on_encoded_audio_buffer_((char *)out_data, ret);
} else {
OnEncodedAudioBuffer((char *)out_data, ret);
}
return 0;
}
int AudioEncoder::OnEncodedAudioBuffer(char *encoded_audio_buffer,
size_t size) {
LOG_INFO("OnEncodedAudioBuffer not implemented");
return 0;
}

View File

@@ -0,0 +1,41 @@
/*
* @Author: DI JUNKUN
* @Date: 2023-11-24
* Copyright (c) 2023 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _AUDIO_ENCODER_H_
#define _AUDIO_ENCODER_H_
#include <functional>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
#include "opus/opus.h"
class AudioEncoder {
public:
AudioEncoder(int sample_rate, int channel_num, int frame_size);
~AudioEncoder();
public:
int Init();
int Encode(const uint8_t* data, int size,
std::function<int(char* encoded_audio_buffer, size_t size)>
on_encoded_audio_buffer);
int OnEncodedAudioBuffer(char* encoded_audio_buffer, size_t size);
private:
OpusEncoder* opus_encoder_ = nullptr;
int sample_rate_ = 48000;
int channel_num_ = 1;
int frame_size_ = 480;
std::queue<unsigned char> pcm_queue;
std::function<int(char* encoded_audio_buffer, size_t size)>
on_encoded_audio_buffer_ = nullptr;
};
#endif

View File

@@ -1,9 +1,15 @@
/*
* @Author: DI JUNKUN
* @Date: 2023-11-24
* Copyright (c) 2023 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _VIDEO_DECODER_H_
#define _VIDEO_DECODER_H_
#include <functional>
#include "frame.h"
#include "video_frame.h"
class VideoDecoder {
public: