1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <netinet/in.h> 7 #include <sbc/sbc.h> 8 #include <syslog.h> 9 10 #include "cras_a2dp_info.h" 11 #include "cras_sbc_codec.h" 12 #include "cras_types.h" 13 #include "rtp.h" 14 15 int init_a2dp(struct a2dp_info *a2dp, a2dp_sbc_t *sbc) 16 { 17 uint8_t frequency = 0, mode = 0, subbands = 0, allocation, blocks = 0, 18 bitpool; 19 20 if (sbc->frequency & SBC_SAMPLING_FREQ_48000) 21 frequency = SBC_FREQ_48000; 22 else if (sbc->frequency & SBC_SAMPLING_FREQ_44100) 23 frequency = SBC_FREQ_44100; 24 else if (sbc->frequency & SBC_SAMPLING_FREQ_32000) 25 frequency = SBC_FREQ_32000; 26 else if (sbc->frequency & SBC_SAMPLING_FREQ_16000) 27 frequency = SBC_FREQ_16000; 28 29 if (sbc->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) 30 mode = SBC_MODE_JOINT_STEREO; 31 else if (sbc->channel_mode & SBC_CHANNEL_MODE_STEREO) 32 mode = SBC_MODE_STEREO; 33 else if (sbc->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL) 34 mode = SBC_MODE_DUAL_CHANNEL; 35 else if (sbc->channel_mode & SBC_CHANNEL_MODE_MONO) 36 mode = SBC_MODE_MONO; 37 38 if (sbc->allocation_method & SBC_ALLOCATION_LOUDNESS) 39 allocation = SBC_AM_LOUDNESS; 40 else 41 allocation = SBC_AM_SNR; 42 43 switch (sbc->subbands) { 44 case SBC_SUBBANDS_4: 45 subbands = SBC_SB_4; 46 break; 47 case SBC_SUBBANDS_8: 48 subbands = SBC_SB_8; 49 break; 50 } 51 52 switch (sbc->block_length) { 53 case SBC_BLOCK_LENGTH_4: 54 blocks = SBC_BLK_4; 55 break; 56 case SBC_BLOCK_LENGTH_8: 57 blocks = SBC_BLK_8; 58 break; 59 case SBC_BLOCK_LENGTH_12: 60 blocks = SBC_BLK_12; 61 break; 62 case SBC_BLOCK_LENGTH_16: 63 blocks = SBC_BLK_16; 64 break; 65 } 66 67 bitpool = sbc->max_bitpool; 68 69 a2dp->codec = cras_sbc_codec_create(frequency, mode, subbands, 70 allocation, blocks, bitpool); 71 if (!a2dp->codec) 72 return -1; 73 74 /* SBC info */ 75 a2dp->codesize = cras_sbc_get_codesize(a2dp->codec); 76 a2dp->frame_length = cras_sbc_get_frame_length(a2dp->codec); 77 78 a2dp->a2dp_buf_used = sizeof(struct rtp_header) 79 + sizeof(struct rtp_payload); 80 a2dp->frame_count = 0; 81 a2dp->seq_num = 0; 82 a2dp->samples = 0; 83 84 return 0; 85 } 86 87 void destroy_a2dp(struct a2dp_info *a2dp) 88 { 89 cras_sbc_codec_destroy(a2dp->codec); 90 } 91 92 int a2dp_codesize(struct a2dp_info *a2dp) 93 { 94 return a2dp->codesize; 95 } 96 97 int a2dp_block_size(struct a2dp_info *a2dp, int a2dp_bytes) 98 { 99 return a2dp_bytes / a2dp->frame_length * a2dp->codesize; 100 } 101 102 int a2dp_queued_frames(const struct a2dp_info *a2dp) 103 { 104 return a2dp->samples; 105 } 106 107 void a2dp_drain(struct a2dp_info *a2dp) 108 { 109 a2dp->a2dp_buf_used = sizeof(struct rtp_header) 110 + sizeof(struct rtp_payload); 111 a2dp->samples = 0; 112 a2dp->seq_num = 0; 113 a2dp->frame_count = 0; 114 } 115 116 static int avdtp_write(int stream_fd, struct a2dp_info *a2dp) 117 { 118 int err, samples; 119 struct rtp_header *header; 120 struct rtp_payload *payload; 121 122 header = (struct rtp_header *)a2dp->a2dp_buf; 123 payload = (struct rtp_payload *)(a2dp->a2dp_buf + sizeof(*header)); 124 memset(a2dp->a2dp_buf, 0, sizeof(*header) + sizeof(*payload)); 125 126 payload->frame_count = a2dp->frame_count; 127 header->v = 2; 128 header->pt = 1; 129 header->sequence_number = htons(a2dp->seq_num); 130 header->timestamp = htonl(a2dp->nsamples); 131 header->ssrc = htonl(1); 132 133 err = send(stream_fd, a2dp->a2dp_buf, a2dp->a2dp_buf_used, 134 MSG_DONTWAIT); 135 if (err < 0) 136 return -errno; 137 138 /* Returns the number of samples in frame. */ 139 samples = a2dp->samples; 140 141 /* Reset some data */ 142 a2dp->a2dp_buf_used = sizeof(*header) + sizeof(*payload); 143 a2dp->frame_count = 0; 144 a2dp->samples = 0; 145 a2dp->seq_num++; 146 147 return samples; 148 } 149 150 int a2dp_encode(struct a2dp_info *a2dp, const void *pcm_buf, int pcm_buf_size, 151 int format_bytes, size_t link_mtu) 152 { 153 int processed; 154 size_t out_encoded; 155 156 if (link_mtu > A2DP_BUF_SIZE_BYTES) 157 link_mtu = A2DP_BUF_SIZE_BYTES; 158 if (link_mtu == a2dp->a2dp_buf_used) 159 return 0; 160 161 processed = a2dp->codec->encode(a2dp->codec, pcm_buf, pcm_buf_size, 162 a2dp->a2dp_buf + a2dp->a2dp_buf_used, 163 link_mtu - a2dp->a2dp_buf_used, 164 &out_encoded); 165 if (processed < 0) { 166 syslog(LOG_ERR, "a2dp encode error %d", processed); 167 return processed; 168 } 169 170 if (a2dp->codesize > 0) 171 a2dp->frame_count += processed / a2dp->codesize; 172 a2dp->a2dp_buf_used += out_encoded; 173 174 a2dp->samples += processed / format_bytes; 175 a2dp->nsamples += processed / format_bytes; 176 177 return processed; 178 } 179 180 int a2dp_write(struct a2dp_info *a2dp, int stream_fd, size_t link_mtu) 181 { 182 /* Do avdtp write when the max number of SBC frames is reached. */ 183 if (a2dp->a2dp_buf_used + a2dp->frame_length > 184 link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload)) 185 return avdtp_write(stream_fd, a2dp); 186 187 return 0; 188 } 189