a2dp: improve a2dp sink codec data flushing

Let codec decides when rtp packet need to be sent (terminated by MTU size in most case).
LDAC encoding loop can now be terminated by reading if frame_num is written, no 'frame_count' updating is needed.
RTP payload fragmentation can now be implemented more easily based on this.
This commit is contained in:
Huang-Huang Bao 2021-03-31 17:50:15 +08:00 committed by Wim Taymans
parent 7b9792ffab
commit 5c93f780cf
6 changed files with 56 additions and 170 deletions

View file

@ -43,6 +43,8 @@ struct impl {
size_t mtu;
int codesize;
int frame_length;
int frame_count;
int max_frames;
bool hd;
};
@ -202,19 +204,6 @@ static int codec_increase_bitpool(void *data)
return -ENOTSUP;
}
static int codec_get_num_blocks(void *data)
{
struct impl *this = data;
size_t frame_count;
if (this->hd)
frame_count = (this->mtu - sizeof(struct rtp_header)) / this->frame_length;
else
frame_count = this->mtu / this->frame_length;
return frame_count;
}
static int codec_get_block_size(void *data)
{
struct impl *this = data;
@ -247,6 +236,11 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
this->frame_length = this->hd ? 6 : 4;
this->codesize = 4 * 3 * 2;
if (this->hd)
this->max_frames = (this->mtu - sizeof(struct rtp_header)) / this->frame_length;
else
this->max_frames = this->mtu / this->frame_length;
return this;
error_errno:
@ -277,6 +271,8 @@ static int codec_start_encode (void *data,
{
struct impl *this = data;
this->frame_count = 0;
if (!this->hd)
return 0;
@ -287,21 +283,31 @@ static int codec_start_encode (void *data,
this->header->pt = 1;
this->header->sequence_number = htons(seqnum);
this->header->timestamp = htonl(timestamp);
this->header->ssrc = htonl(1);
return sizeof(struct rtp_header);
}
static int codec_encode(void *data,
const void *src, size_t src_size,
void *dst, size_t dst_size,
size_t *dst_out)
size_t *dst_out, int *need_flush)
{
struct impl *this = data;
size_t avail_dst_size;
int res;
res = aptx_encode(this->aptx, src, src_size,
dst, dst_size, dst_out);
avail_dst_size = (this->max_frames - this->frame_count) * this->frame_length;
if (SPA_UNLIKELY(dst_size < avail_dst_size)) {
*need_flush = 1;
return 0;
}
res = aptx_encode(this->aptx, src, src_size,
dst, avail_dst_size, dst_out);
if(SPA_UNLIKELY(res < 0))
return -EINVAL;
this->frame_count += *dst_out / this->frame_length;
*need_flush = this->frame_count >= this->max_frames;
return res;
}
@ -352,7 +358,6 @@ const struct a2dp_codec a2dp_codec_aptx = {
.init = codec_init,
.deinit = codec_deinit,
.get_block_size = codec_get_block_size,
.get_num_blocks = codec_get_num_blocks,
.abr_process = codec_abr_process,
.start_encode = codec_start_encode,
.encode = codec_encode,
@ -376,7 +381,6 @@ const struct a2dp_codec a2dp_codec_aptx_hd = {
.init = codec_init,
.deinit = codec_deinit,
.get_block_size = codec_get_block_size,
.get_num_blocks = codec_get_num_blocks,
.abr_process = codec_abr_process,
.start_encode = codec_start_encode,
.encode = codec_encode,