Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,136 @@
|
|||
#include "AudioStreamingPartPersistentDecoder.h"
|
||||
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/third_party/base64/base64.h"
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
WrappedCodecParameters::WrappedCodecParameters(AVCodecParameters const *codecParameters) {
|
||||
_value = avcodec_parameters_alloc();
|
||||
avcodec_parameters_copy(_value, codecParameters);
|
||||
}
|
||||
|
||||
WrappedCodecParameters::~WrappedCodecParameters() {
|
||||
avcodec_parameters_free(&_value);
|
||||
}
|
||||
|
||||
bool WrappedCodecParameters::isEqual(AVCodecParameters const *other) {
|
||||
if (_value->codec_id != other->codec_id) {
|
||||
return false;
|
||||
}
|
||||
if (_value->format != other->format) {
|
||||
return false;
|
||||
}
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 59
|
||||
if (_value->ch_layout.nb_channels != other->ch_layout.nb_channels) {
|
||||
#else
|
||||
if (_value->channels != other->channels) {
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class AudioStreamingPartPersistentDecoderState {
|
||||
public:
|
||||
AudioStreamingPartPersistentDecoderState(AVCodecParameters const *codecParameters, AVRational timeBase) :
|
||||
_codecParameters(codecParameters),
|
||||
_timeBase(timeBase) {
|
||||
const AVCodec *codec = avcodec_find_decoder(codecParameters->codec_id);
|
||||
if (codec) {
|
||||
_codecContext = avcodec_alloc_context3(codec);
|
||||
int ret = avcodec_parameters_to_context(_codecContext, codecParameters);
|
||||
if (ret < 0) {
|
||||
avcodec_free_context(&_codecContext);
|
||||
_codecContext = nullptr;
|
||||
} else {
|
||||
_codecContext->pkt_timebase = timeBase;
|
||||
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 59
|
||||
_channelCount = _codecContext->ch_layout.nb_channels;
|
||||
#else
|
||||
_channelCount = _codecContext->channels;
|
||||
#endif
|
||||
|
||||
ret = avcodec_open2(_codecContext, codec, nullptr);
|
||||
if (ret < 0) {
|
||||
avcodec_free_context(&_codecContext);
|
||||
_codecContext = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~AudioStreamingPartPersistentDecoderState() {
|
||||
if (_codecContext) {
|
||||
avcodec_close(_codecContext);
|
||||
avcodec_free_context(&_codecContext);
|
||||
}
|
||||
}
|
||||
|
||||
int decode(AVPacket &packet, AVFrame *frame) {
|
||||
int ret = avcodec_send_packet(_codecContext, &packet);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bytesPerSample = av_get_bytes_per_sample(_codecContext->sample_fmt);
|
||||
if (bytesPerSample != 2 && bytesPerSample != 4) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(_codecContext, frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public:
|
||||
WrappedCodecParameters _codecParameters;
|
||||
AVRational _timeBase;
|
||||
AVCodecContext *_codecContext = nullptr;
|
||||
int _channelCount = 0;
|
||||
};
|
||||
|
||||
AudioStreamingPartPersistentDecoder::AudioStreamingPartPersistentDecoder() {
|
||||
}
|
||||
|
||||
AudioStreamingPartPersistentDecoder::~AudioStreamingPartPersistentDecoder() {
|
||||
if (_state) {
|
||||
delete _state;
|
||||
_state = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioStreamingPartPersistentDecoder::maybeReset(AVCodecParameters const *codecParameters, AVRational timeBase) {
|
||||
if (_state) {
|
||||
bool isUpdated = false;
|
||||
if (!_state->_codecParameters.isEqual(codecParameters)) {
|
||||
isUpdated = true;
|
||||
}
|
||||
if (_state->_timeBase.num != timeBase.num || _state->_timeBase.den != timeBase.den) {
|
||||
isUpdated = true;
|
||||
}
|
||||
if (!isUpdated) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_state) {
|
||||
delete _state;
|
||||
_state = nullptr;
|
||||
}
|
||||
|
||||
_state = new AudioStreamingPartPersistentDecoderState(codecParameters, timeBase);
|
||||
}
|
||||
|
||||
int AudioStreamingPartPersistentDecoder::decode(AVCodecParameters const *codecParameters, AVRational timeBase, AVPacket &packet, AVFrame *frame) {
|
||||
maybeReset(codecParameters, timeBase);
|
||||
|
||||
if (!_state) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _state->decode(packet, frame);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue