mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Opus codec module test pass
This commit is contained in:
66
src/media/audio/decode/audio_decoder.cpp
Normal file
66
src/media/audio/decode/audio_decoder.cpp
Normal 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;
|
||||
}
|
||||
42
src/media/audio/decode/audio_decoder.h
Normal file
42
src/media/audio/decode/audio_decoder.h
Normal 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
|
||||
93
src/media/audio/encode/audio_encoder.cpp
Normal file
93
src/media/audio/encode/audio_encoder.cpp
Normal 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;
|
||||
}
|
||||
41
src/media/audio/encode/audio_encoder.h
Normal file
41
src/media/audio/encode/audio_encoder.h
Normal 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
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user