mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
bluez5: Add AAC decoder
This commit is contained in:
parent
6d4d77802a
commit
76adcfaabe
1 changed files with 95 additions and 0 deletions
|
|
@ -31,10 +31,16 @@
|
||||||
#include <spa/utils/dict.h>
|
#include <spa/utils/dict.h>
|
||||||
|
|
||||||
#include <fdk-aac/aacenc_lib.h>
|
#include <fdk-aac/aacenc_lib.h>
|
||||||
|
#include <fdk-aac/aacdecoder_lib.h>
|
||||||
|
|
||||||
#include "rtp.h"
|
#include "rtp.h"
|
||||||
#include "a2dp-codecs.h"
|
#include "a2dp-codecs.h"
|
||||||
|
|
||||||
|
static struct spa_log *log;
|
||||||
|
static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.aac");
|
||||||
|
#undef SPA_LOG_TOPIC_DEFAULT
|
||||||
|
#define SPA_LOG_TOPIC_DEFAULT &log_topic
|
||||||
|
|
||||||
#define DEFAULT_AAC_BITRATE 320000
|
#define DEFAULT_AAC_BITRATE 320000
|
||||||
#define MIN_AAC_BITRATE 64000
|
#define MIN_AAC_BITRATE 64000
|
||||||
|
|
||||||
|
|
@ -44,6 +50,7 @@ struct props {
|
||||||
|
|
||||||
struct impl {
|
struct impl {
|
||||||
HANDLE_AACENCODER aacenc;
|
HANDLE_AACENCODER aacenc;
|
||||||
|
HANDLE_AACDECODER aacdec;
|
||||||
|
|
||||||
struct rtp_header *header;
|
struct rtp_header *header;
|
||||||
|
|
||||||
|
|
@ -412,11 +419,39 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
|
||||||
|
|
||||||
this->codesize = enc_info.frameLength * this->channels * this->samplesize;
|
this->codesize = enc_info.frameLength * this->channels * this->samplesize;
|
||||||
|
|
||||||
|
this->aacdec = aacDecoder_Open(TT_MP4_LATM_MCP1, 1);
|
||||||
|
if (!this->aacdec) {
|
||||||
|
res = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AACDECODER_LIB_VL0
|
||||||
|
res = aacDecoder_SetParam(this->aacdec, AAC_PCM_MIN_OUTPUT_CHANNELS, this->channels);
|
||||||
|
if (res != AAC_DEC_OK) {
|
||||||
|
spa_log_debug(log, "Couldn't set min output channels: 0x%04X", res);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = aacDecoder_SetParam(this->aacdec, AAC_PCM_MAX_OUTPUT_CHANNELS, this->channels);
|
||||||
|
if (res != AAC_DEC_OK) {
|
||||||
|
spa_log_debug(log, "Couldn't set max output channels: 0x%04X", res);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
res = aacDecoder_SetParam(this->aacdec, AAC_PCM_OUTPUT_CHANNELS, this->channels);
|
||||||
|
if (res != AAC_DEC_OK) {
|
||||||
|
spa_log_debug(log, "Couldn't set output channels: 0x%04X", res);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (this && this->aacenc)
|
if (this && this->aacenc)
|
||||||
aacEncClose(&this->aacenc);
|
aacEncClose(&this->aacenc);
|
||||||
|
if (this && this->aacdec)
|
||||||
|
aacDecoder_Close(this->aacdec);
|
||||||
free(this);
|
free(this);
|
||||||
errno = -res;
|
errno = -res;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -427,6 +462,8 @@ static void codec_deinit(void *data)
|
||||||
struct impl *this = data;
|
struct impl *this = data;
|
||||||
if (this->aacenc)
|
if (this->aacenc)
|
||||||
aacEncClose(&this->aacenc);
|
aacEncClose(&this->aacenc);
|
||||||
|
if (this->aacdec)
|
||||||
|
aacDecoder_Close(this->aacdec);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,6 +539,55 @@ static int codec_encode(void *data,
|
||||||
return out_args.numInSamples * this->samplesize;
|
return out_args.numInSamples * this->samplesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int codec_start_decode (void *data,
|
||||||
|
const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp)
|
||||||
|
{
|
||||||
|
const struct rtp_header *header = src;
|
||||||
|
size_t header_size = sizeof(struct rtp_header);
|
||||||
|
|
||||||
|
spa_return_val_if_fail (src_size > header_size, -EINVAL);
|
||||||
|
|
||||||
|
if (seqnum)
|
||||||
|
*seqnum = ntohs(header->sequence_number);
|
||||||
|
if (timestamp)
|
||||||
|
*timestamp = ntohl(header->timestamp);
|
||||||
|
|
||||||
|
return header_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int codec_decode(void *data,
|
||||||
|
const void *src, size_t src_size,
|
||||||
|
void *dst, size_t dst_size,
|
||||||
|
size_t *dst_out)
|
||||||
|
{
|
||||||
|
struct impl *this = data;
|
||||||
|
uint data_size = (uint)src_size;
|
||||||
|
uint bytes_valid = data_size;
|
||||||
|
CStreamInfo *aacinf;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = aacDecoder_Fill(this->aacdec, (UCHAR **)&src, &data_size, &bytes_valid);
|
||||||
|
if (res != AAC_DEC_OK) {
|
||||||
|
spa_log_debug(log, "AAC buffer fill error: 0x%04X", res);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = aacDecoder_DecodeFrame(this->aacdec, dst, dst_size, 0);
|
||||||
|
if (res != AAC_DEC_OK) {
|
||||||
|
spa_log_debug(log, "AAC decode frame error: 0x%04X", res);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
aacinf = aacDecoder_GetStreamInfo(this->aacdec);
|
||||||
|
if (!aacinf) {
|
||||||
|
spa_log_debug(log, "AAC get stream info failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
*dst_out = aacinf->frameSize * aacinf->numChannels * this->samplesize;
|
||||||
|
|
||||||
|
return src_size - bytes_valid;
|
||||||
|
}
|
||||||
|
|
||||||
static int codec_abr_process (void *data, size_t unsent)
|
static int codec_abr_process (void *data, size_t unsent)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|
@ -538,6 +624,12 @@ static int codec_increase_bitpool(void *data)
|
||||||
return codec_change_bitrate(this, (this->cur_bitrate * 4) / 3);
|
return codec_change_bitrate(this, (this->cur_bitrate * 4) / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void codec_set_log(struct spa_log *global_log)
|
||||||
|
{
|
||||||
|
log = global_log;
|
||||||
|
spa_log_topic_init(log, &log_topic);
|
||||||
|
}
|
||||||
|
|
||||||
const struct a2dp_codec a2dp_codec_aac = {
|
const struct a2dp_codec a2dp_codec_aac = {
|
||||||
.id = SPA_BLUETOOTH_AUDIO_CODEC_AAC,
|
.id = SPA_BLUETOOTH_AUDIO_CODEC_AAC,
|
||||||
.codec_id = A2DP_CODEC_MPEG24,
|
.codec_id = A2DP_CODEC_MPEG24,
|
||||||
|
|
@ -554,9 +646,12 @@ const struct a2dp_codec a2dp_codec_aac = {
|
||||||
.get_block_size = codec_get_block_size,
|
.get_block_size = codec_get_block_size,
|
||||||
.start_encode = codec_start_encode,
|
.start_encode = codec_start_encode,
|
||||||
.encode = codec_encode,
|
.encode = codec_encode,
|
||||||
|
.start_decode = codec_start_decode,
|
||||||
|
.decode = codec_decode,
|
||||||
.abr_process = codec_abr_process,
|
.abr_process = codec_abr_process,
|
||||||
.reduce_bitpool = codec_reduce_bitpool,
|
.reduce_bitpool = codec_reduce_bitpool,
|
||||||
.increase_bitpool = codec_increase_bitpool,
|
.increase_bitpool = codec_increase_bitpool,
|
||||||
|
.set_log = codec_set_log,
|
||||||
};
|
};
|
||||||
|
|
||||||
A2DP_CODEC_EXPORT_DEF(
|
A2DP_CODEC_EXPORT_DEF(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue