diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-01-23 13:16:02 +0000 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-01-23 13:16:02 +0000 | 
| commit | 489c2e0dbd76d9cecec62d19fafd9e7baddb72e7 (patch) | |
| tree | d8ec2cba32e8a20443eb85e4162d0b38f0fd0d31 | |
| parent | a0af7ee44534dad8f35a4142c6a22177e54ffc57 (diff) | |
Add mpeg12 sep registration.
| -rw-r--r-- | audio/a2dp.c | 144 | ||||
| -rw-r--r-- | audio/a2dp.h | 13 | ||||
| -rw-r--r-- | audio/avdtp.c | 2 | ||||
| -rw-r--r-- | audio/avdtp.h | 1 | ||||
| -rw-r--r-- | audio/gsta2dpsendersink.c | 37 | ||||
| -rw-r--r-- | audio/ipc.h | 20 | ||||
| -rw-r--r-- | audio/pcm_bluetooth.c | 39 | ||||
| -rw-r--r-- | audio/unix.c | 62 | 
8 files changed, 247 insertions, 71 deletions
| diff --git a/audio/a2dp.c b/audio/a2dp.c index 1c59374f..b1409f5c 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -58,6 +58,7 @@  struct a2dp_sep {  	uint8_t type; +	uint8_t codec;  	struct avdtp_local_sep *sep;  	struct avdtp *session;  	struct avdtp_stream *stream; @@ -280,7 +281,7 @@ static void stream_state_changed(struct avdtp_stream *stream,  } -static gboolean setconf_ind(struct avdtp *session, +static gboolean sbc_setconf_ind(struct avdtp *session,  				struct avdtp_local_sep *sep,  				struct avdtp_stream *stream,  				GSList *caps, uint8_t *err, @@ -331,7 +332,7 @@ static gboolean setconf_ind(struct avdtp *session,  	return TRUE;  } -static gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep, +static gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,  				GSList **caps, uint8_t *err, void *user_data)  {  	struct a2dp_sep *a2dp_sep = user_data; @@ -386,6 +387,84 @@ static gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,  	return TRUE;  } +static gboolean mpeg_setconf_ind(struct avdtp *session, +				struct avdtp_local_sep *sep, +				struct avdtp_stream *stream, +				GSList *caps, uint8_t *err, +				uint8_t *category, void *user_data) +{ +	struct a2dp_sep *a2dp_sep = user_data; +	struct device *dev; + +	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) +		debug("SBC Sink: Set_Configuration_Ind"); +	else +		debug("SBC Source: Set_Configuration_Ind"); + +	dev = a2dp_get_dev(session); +	if (!dev) { +		*err = AVDTP_UNSUPPORTED_CONFIGURATION; +		*category = 0x00; +		return FALSE; +	} + +	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); +	a2dp_sep->stream = stream; + +	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) +		sink_new_stream(dev, session, stream); + +	return TRUE; +} + +static gboolean mpeg_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep, +				GSList **caps, uint8_t *err, void *user_data) +{ +	struct a2dp_sep *a2dp_sep = user_data; +	struct avdtp_service_capability *media_transport, *media_codec; +	struct mpeg_codec_cap mpeg_cap; + +	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) +		debug("SBC Sink: Get_Capability_Ind"); +	else +		debug("SBC Source: Get_Capability_Ind"); + +	*caps = NULL; + +	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, +						NULL, 0); + +	*caps = g_slist_append(*caps, media_transport); + +	memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap)); + +	mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; +	mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12; + +	mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 | +				MPEG_SAMPLING_FREQ_44100 | +				MPEG_SAMPLING_FREQ_32000 | +				MPEG_SAMPLING_FREQ_24000 | +				MPEG_SAMPLING_FREQ_22050 | +				MPEG_SAMPLING_FREQ_16000 ); + +	mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO | +					MPEG_CHANNEL_MODE_STEREO | +					MPEG_CHANNEL_MODE_DUAL_CHANNEL | +					MPEG_CHANNEL_MODE_MONO ); + +	mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 ); + +	mpeg_cap.bitrate = 0xFFFF; + +	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap, +						sizeof(mpeg_cap)); + +	*caps = g_slist_append(*caps, media_codec); + +	return TRUE; +} +  static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  				struct avdtp_stream *stream,  				struct avdtp_error *err, void *user_data) @@ -797,9 +876,21 @@ static struct avdtp_sep_cfm cfm = {  	.reconfigure		= reconf_cfm  }; -static struct avdtp_sep_ind ind = { -	.get_capability		= getcap_ind, -	.set_configuration	= setconf_ind, +static struct avdtp_sep_ind sbc_ind = { +	.get_capability		= sbc_getcap_ind, +	.set_configuration	= sbc_setconf_ind, +	.get_configuration	= getconf_ind, +	.open			= open_ind, +	.start			= start_ind, +	.suspend		= suspend_ind, +	.close			= close_ind, +	.abort			= abort_ind, +	.reconfigure		= reconf_ind +}; + +static struct avdtp_sep_ind mpeg_ind = { +	.get_capability		= mpeg_getcap_ind, +	.set_configuration	= mpeg_setconf_ind,  	.get_configuration	= getconf_ind,  	.open			= open_ind,  	.start			= start_ind, @@ -880,23 +971,27 @@ static int a2dp_sink_record(sdp_buf_t *buf)  	return 0;  } -static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type) +static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type, +					uint8_t codec)  {  	struct a2dp_sep *sep;  	GSList **l;  	int (*create_record)(sdp_buf_t *buf);  	uint32_t *record_id;  	sdp_buf_t buf; +	struct avdtp_sep_ind *ind;  	sep = g_new0(struct a2dp_sep, 1); -	sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, -					&ind, &cfm, sep); +	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind; +	sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, codec, +					ind, &cfm, sep);  	if (sep->sep == NULL) {  		g_free(sep);  		return NULL;  	} +	sep->codec = codec;  	sep->type = type;  	if (type == AVDTP_SEP_TYPE_SOURCE) { @@ -945,11 +1040,15 @@ int a2dp_init(DBusConnection *conn, int sources, int sinks)  	avdtp_init(); -	for (i = 0; i < sources; i++) -		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE); +	for (i = 0; i < sources; i++) { +		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE, A2DP_CODEC_SBC); +		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE, A2DP_CODEC_MPEG12); +	} -	for (i = 0; i < sinks; i++) -		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK); +	for (i = 0; i < sinks; i++) { +		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK, A2DP_CODEC_SBC); +		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK, A2DP_CODEC_MPEG12); +	}  	return 0;  } @@ -1025,14 +1124,32 @@ unsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,  	struct a2dp_sep *sep = NULL;  	struct avdtp_local_sep *lsep;  	struct avdtp_remote_sep *rsep; +	struct avdtp_service_capability *cap; +	struct avdtp_media_codec_capability *codec_cap = NULL;  	int posix_err; +	for (l = caps; l != NULL; l = l->next) { +		cap = l->data; + +		if (cap->category != AVDTP_MEDIA_CODEC) +			continue; + +		codec_cap = (void *) cap->data; +		break; +	} + +	if (!codec_cap) +		return 0; +  	for (l = sources; l != NULL; l = l->next) {  		struct a2dp_sep *tmp = l->data;  		if (tmp->locked)  			continue; +		if (tmp->codec != codec_cap->media_codec_type) +			continue; +  		if (!tmp->stream || avdtp_has_stream(session, tmp->stream)) {  			sep = tmp;  			break; @@ -1067,7 +1184,8 @@ unsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,  	switch (avdtp_sep_get_state(sep->sep)) {  	case AVDTP_STATE_IDLE:  		if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, -				AVDTP_MEDIA_TYPE_AUDIO, A2DP_CODEC_SBC, +				codec_cap->media_type, +				codec_cap->media_codec_type,  				&lsep, &rsep) < 0) {  			error("No matching ACP and INT SEPs found");  			goto failed; diff --git a/audio/a2dp.h b/audio/a2dp.h index cfd1c47d..84301bad 100644 --- a/audio/a2dp.h +++ b/audio/a2dp.h @@ -48,6 +48,11 @@  #define SBC_ALLOCATION_SNR		(1 << 1)  #define SBC_ALLOCATION_LOUDNESS		1 +#define MPEG_CHANNEL_MODE_MONO		(1 << 3) +#define MPEG_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2) +#define MPEG_CHANNEL_MODE_STEREO	(1 << 1) +#define MPEG_CHANNEL_MODE_JOINT_STEREO	1 +  #define MPEG_LAYER_MP1			(1 << 2)  #define MPEG_LAYER_MP2			(1 << 1)  #define MPEG_LAYER_MP3			1 @@ -83,9 +88,7 @@ struct mpeg_codec_cap {  	uint8_t frequency:6;  	uint8_t mpf:1;  	uint8_t rfa:1; -	uint8_t bitrate0:7; -	uint8_t vbr:1; -	uint8_t bitrate1; +	uint16_t bitrate;  } __attribute__ ((packed));  #elif __BYTE_ORDER == __BIG_ENDIAN @@ -109,9 +112,7 @@ struct mpeg_codec_cap {  	uint8_t rfa:1;  	uint8_t mpf:1;  	uint8_t frequency:6; -	uint8_t vbr:1; -	uint8_t bitrate0:7; -	uint8_t bitrate1; +	uint16_t bitrate;  } __attribute__ ((packed));  #else diff --git a/audio/avdtp.c b/audio/avdtp.c index d5433452..97868a07 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -2696,6 +2696,7 @@ int avdtp_abort(struct avdtp *session, struct avdtp_stream *stream)  }  struct avdtp_local_sep *avdtp_register_sep(uint8_t type, uint8_t media_type, +						uint8_t codec_type,  						struct avdtp_sep_ind *ind,  						struct avdtp_sep_cfm *cfm,  						void *user_data) @@ -2711,6 +2712,7 @@ struct avdtp_local_sep *avdtp_register_sep(uint8_t type, uint8_t media_type,  	sep->info.seid = free_seid++;  	sep->info.type = type;  	sep->info.media_type = media_type; +	sep->codec = codec_type;  	sep->ind = ind;  	sep->cfm = cfm;  	sep->user_data = user_data; diff --git a/audio/avdtp.h b/audio/avdtp.h index 241fa713..01ca50c6 100644 --- a/audio/avdtp.h +++ b/audio/avdtp.h @@ -242,6 +242,7 @@ int avdtp_close(struct avdtp *session, struct avdtp_stream *stream);  int avdtp_abort(struct avdtp *session, struct avdtp_stream *stream);  struct avdtp_local_sep *avdtp_register_sep(uint8_t type, uint8_t media_type, +						uint8_t codec_type,  						struct avdtp_sep_ind *ind,  						struct avdtp_sep_cfm *cfm,  						void *user_data); diff --git a/audio/gsta2dpsendersink.c b/audio/gsta2dpsendersink.c index cfb67b87..1f54f29c 100644 --- a/audio/gsta2dpsendersink.c +++ b/audio/gsta2dpsendersink.c @@ -236,13 +236,13 @@ static gboolean gst_a2dp_sender_sink_init_pkt_conf(GstA2dpSenderSink *sink,  	value = gst_structure_get_value(structure, "rate");  	rate = g_value_get_int(value);  	if (rate == 44100) -		cfg->frequency = BT_A2DP_SAMPLING_FREQ_44100; +		cfg->frequency = BT_SBC_SAMPLING_FREQ_44100;  	else if (rate == 48000) -		cfg->frequency = BT_A2DP_SAMPLING_FREQ_48000; +		cfg->frequency = BT_SBC_SAMPLING_FREQ_48000;  	else if (rate == 32000) -		cfg->frequency = BT_A2DP_SAMPLING_FREQ_32000; +		cfg->frequency = BT_SBC_SAMPLING_FREQ_32000;  	else if (rate == 16000) -		cfg->frequency = BT_A2DP_SAMPLING_FREQ_16000; +		cfg->frequency = BT_SBC_SAMPLING_FREQ_16000;  	else {  		GST_ERROR_OBJECT(sink, "Invalid rate while setting caps");  		return FALSE; @@ -396,17 +396,14 @@ static gboolean server_callback(GIOChannel *chan,  	return TRUE;  } -static gboolean gst_a2dp_sender_sink_update_caps(GstA2dpSenderSink *self) +static GstStructure *gst_a2dp_sender_sink_parse_sbc_caps( +			GstA2dpSenderSink *self, sbc_capabilities_t *sbc)  { -	sbc_capabilities_t *sbc = &self->data->caps.sbc_capabilities;  	GstStructure *structure;  	GValue *value;  	GValue *list; -	gchar *tmp;  	gboolean mono, stereo; -	GST_LOG_OBJECT(self, "updating device caps"); -  	structure = gst_structure_empty_new("audio/x-sbc");  	value = g_value_init(g_new0(GValue, 1), G_TYPE_STRING); @@ -518,19 +515,19 @@ static gboolean gst_a2dp_sender_sink_update_caps(GstA2dpSenderSink *self)  	/* rate */  	g_value_init(value, G_TYPE_INT);  	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST); -	if (sbc->frequency & BT_A2DP_SAMPLING_FREQ_48000) { +	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_48000) {  		g_value_set_int(value, 48000);  		gst_value_list_prepend_value(list, value);  	} -	if (sbc->frequency & BT_A2DP_SAMPLING_FREQ_44100) { +	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_44100) {  		g_value_set_int(value, 44100);  		gst_value_list_prepend_value(list, value);  	} -	if (sbc->frequency & BT_A2DP_SAMPLING_FREQ_32000) { +	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_32000) {  		g_value_set_int(value, 32000);  		gst_value_list_prepend_value(list, value);  	} -	if (sbc->frequency & BT_A2DP_SAMPLING_FREQ_16000) { +	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_16000) {  		g_value_set_int(value, 16000);  		gst_value_list_prepend_value(list, value);  	} @@ -584,6 +581,20 @@ static gboolean gst_a2dp_sender_sink_update_caps(GstA2dpSenderSink *self)  	gst_structure_set_value(structure, "channels", value);  	g_free(value); +	return structure; +} + +static gboolean gst_a2dp_sender_sink_update_caps(GstA2dpSenderSink *self) +{ +	sbc_capabilities_t *sbc = &self->data->caps.sbc_capabilities; +	mpeg_capabilities_t *mpeg = &self->data->caps.mpeg_capabilities; +	GstStructure *structure; +	gchar *tmp; + +	GST_LOG_OBJECT(self, "updating device caps"); + +	structure = gst_a2dp_sender_sink_parse_sbc_caps(self, sbc); +  	if (self->dev_caps != NULL)  		gst_caps_unref(self->dev_caps);  	self->dev_caps = gst_caps_new_full(structure, NULL); diff --git a/audio/ipc.h b/audio/ipc.h index 64ed65a7..3768dcfb 100644 --- a/audio/ipc.h +++ b/audio/ipc.h @@ -129,10 +129,10 @@ struct bt_getcapabilities_req {   * SBC Codec parameters as per A2DP profile 1.0 ยง 4.3   */ -#define BT_A2DP_SAMPLING_FREQ_16000		(1 << 3) -#define BT_A2DP_SAMPLING_FREQ_32000		(1 << 2) -#define BT_A2DP_SAMPLING_FREQ_44100		(1 << 1) -#define BT_A2DP_SAMPLING_FREQ_48000		1 +#define BT_SBC_SAMPLING_FREQ_16000		(1 << 3) +#define BT_SBC_SAMPLING_FREQ_32000		(1 << 2) +#define BT_SBC_SAMPLING_FREQ_44100		(1 << 1) +#define BT_SBC_SAMPLING_FREQ_48000		1  #define BT_A2DP_CHANNEL_MODE_MONO		(1 << 3)  #define BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2) @@ -152,6 +152,17 @@ struct bt_getcapabilities_req {  #define BT_A2DP_ALLOCATION_LOUDNESS		1  #define BT_A2DP_ALLOCATION_AUTO			0 +#define BT_MPEG_SAMPLING_FREQ_16000		(1 << 5) +#define BT_MPEG_SAMPLING_FREQ_22050		(1 << 4) +#define BT_MPEG_SAMPLING_FREQ_24000		(1 << 3) +#define BT_MPEG_SAMPLING_FREQ_32000		(1 << 2) +#define BT_MPEG_SAMPLING_FREQ_44100		(1 << 1) +#define BT_MPEG_SAMPLING_FREQ_48000		1 + +#define BT_MPEG_LAYER_1				(1 << 2) +#define BT_MPEG_LAYER_2				(1 << 1) +#define BT_MPEG_LAYER_3				1 +  typedef struct {  	uint8_t channel_mode;  	uint8_t frequency; @@ -168,7 +179,6 @@ typedef struct {  	uint8_t layer;  	uint8_t frequency;  	uint8_t mpf; -	uint8_t vbr;  	uint16_t bitrate;  } __attribute__ ((packed)) mpeg_capabilities_t; diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c index e81bbc16..a04f18c0 100644 --- a/audio/pcm_bluetooth.c +++ b/audio/pcm_bluetooth.c @@ -468,10 +468,10 @@ static int bluetooth_hsp_hw_params(snd_pcm_ioplug_t *io,  static uint8_t default_bitpool(uint8_t freq, uint8_t mode)  {  	switch (freq) { -	case BT_A2DP_SAMPLING_FREQ_16000: -	case BT_A2DP_SAMPLING_FREQ_32000: +	case BT_SBC_SAMPLING_FREQ_16000: +	case BT_SBC_SAMPLING_FREQ_32000:  		return 53; -	case BT_A2DP_SAMPLING_FREQ_44100: +	case BT_SBC_SAMPLING_FREQ_44100:  		switch (mode) {  		case BT_A2DP_CHANNEL_MODE_MONO:  		case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL: @@ -483,7 +483,7 @@ static uint8_t default_bitpool(uint8_t freq, uint8_t mode)  			DBG("Invalid channel mode %u", mode);  			return 53;  		} -	case BT_A2DP_SAMPLING_FREQ_48000: +	case BT_SBC_SAMPLING_FREQ_48000:  		switch (mode) {  		case BT_A2DP_CHANNEL_MODE_MONO:  		case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL: @@ -508,16 +508,16 @@ static int select_sbc_params(sbc_capabilities_t *cap, unsigned int rate,  	switch (rate) {  	case 48000: -		cap->frequency = BT_A2DP_SAMPLING_FREQ_48000; +		cap->frequency = BT_SBC_SAMPLING_FREQ_48000;  		break;  	case 44100: -		cap->frequency = BT_A2DP_SAMPLING_FREQ_44100; +		cap->frequency = BT_SBC_SAMPLING_FREQ_44100;  		break;  	case 32000: -		cap->frequency = BT_A2DP_SAMPLING_FREQ_32000; +		cap->frequency = BT_SBC_SAMPLING_FREQ_32000;  		break;  	case 16000: -		cap->frequency = BT_A2DP_SAMPLING_FREQ_16000; +		cap->frequency = BT_SBC_SAMPLING_FREQ_16000;  		break;  	default:  		DBG("Rate %d not supported", rate); @@ -641,16 +641,16 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,  		sbc_init(&a2dp->sbc, 0);  	a2dp->sbc_initialized = 1; -	if (active_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_16000) +	if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_16000)  		a2dp->sbc.rate = 16000; -	if (active_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_32000) +	if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_32000)  		a2dp->sbc.rate = 32000; -	if (active_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_44100) +	if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_44100)  		a2dp->sbc.rate = 44100; -	if (active_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_48000) +	if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_48000)  		a2dp->sbc.rate = 48000;  	if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_MONO) @@ -659,7 +659,8 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,  		a2dp->sbc.channels = 2;  	if (active_capabilities.channel_mode & -			(BT_A2DP_CHANNEL_MODE_MONO || BT_A2DP_CHANNEL_MODE_JOINT_STEREO)) +			(BT_A2DP_CHANNEL_MODE_MONO || +			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))  		a2dp->sbc.joint = 1;  	else  		a2dp->sbc.joint = 0; @@ -1231,22 +1232,26 @@ static int bluetooth_a2dp_hw_constraint(snd_pcm_ioplug_t *io)  	/* supported rates */  	rate_count = 0; -	if (a2dp->sbc_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_16000) { +	if (a2dp->sbc_capabilities.frequency & +			BT_SBC_SAMPLING_FREQ_16000) {  		rate_list[rate_count] = 16000;  		rate_count++;  	} -	if (a2dp->sbc_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_32000) { +	if (a2dp->sbc_capabilities.frequency & +			BT_SBC_SAMPLING_FREQ_32000) {  		rate_list[rate_count] = 32000;  		rate_count++;  	} -	if (a2dp->sbc_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_44100) { +	if (a2dp->sbc_capabilities.frequency & +			BT_SBC_SAMPLING_FREQ_44100) {  		rate_list[rate_count] = 44100;  		rate_count++;  	} -	if (a2dp->sbc_capabilities.frequency & BT_A2DP_SAMPLING_FREQ_48000) { +	if (a2dp->sbc_capabilities.frequency & +			BT_SBC_SAMPLING_FREQ_48000) {  		rate_list[rate_count] = 48000;  		rate_count++;  	} diff --git a/audio/unix.c b/audio/unix.c index 2226579d..d71c420a 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -389,9 +389,7 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,  		rsp->mpeg_capabilities.layer = mpeg_cap->layer;  		rsp->mpeg_capabilities.frequency = mpeg_cap->frequency;  		rsp->mpeg_capabilities.mpf = mpeg_cap->mpf; -		rsp->mpeg_capabilities.vbr = mpeg_cap->vbr; -		rsp->mpeg_capabilities.bitrate = mpeg_cap->bitrate1 & -				mpeg_cap->bitrate0 << 8; +		rsp->mpeg_capabilities.bitrate = mpeg_cap->bitrate;  	}  	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); @@ -794,6 +792,7 @@ static void handle_setconfiguration_req(struct unix_client *client,  {  	struct avdtp_service_capability *media_transport, *media_codec;  	struct sbc_codec_cap sbc_cap; +	struct mpeg_codec_cap mpeg_cap;  	struct device *dev;  	bdaddr_t bdaddr;  	int err = 0; @@ -842,20 +841,49 @@ static void handle_setconfiguration_req(struct unix_client *client,  	client->caps = g_slist_append(client->caps, media_transport); -	memset(&sbc_cap, 0, sizeof(sbc_cap)); - -	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; -	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; -	sbc_cap.channel_mode = req->sbc_capabilities.channel_mode; -	sbc_cap.frequency = req->sbc_capabilities.frequency; -	sbc_cap.allocation_method = req->sbc_capabilities.allocation_method; -	sbc_cap.subbands = req->sbc_capabilities.subbands; -	sbc_cap.block_length = req->sbc_capabilities.block_length ; -	sbc_cap.min_bitpool = req->sbc_capabilities.min_bitpool; -	sbc_cap.max_bitpool = req->sbc_capabilities.max_bitpool; - -	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, -						sizeof(sbc_cap)); +	if (req->mpeg_capabilities.frequency) { +		memset(&mpeg_cap, 0, sizeof(mpeg_cap)); + +		mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; +		mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12; +		mpeg_cap.channel_mode = req->mpeg_capabilities.channel_mode; +		mpeg_cap.crc = req->mpeg_capabilities.crc; +		mpeg_cap.layer = req->mpeg_capabilities.layer; +		mpeg_cap.frequency = req->mpeg_capabilities.frequency; +		mpeg_cap.mpf = req->mpeg_capabilities.mpf; +		mpeg_cap.bitrate = req->mpeg_capabilities.bitrate; + +		media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap, +							sizeof(mpeg_cap)); + +		info("config mpeg - frequency = %u channel_mode = %u " +			"layer = %u crc = %u mpf = %u bitrate = %u", +			mpeg_cap.frequency, mpeg_cap.channel_mode, +			mpeg_cap.layer, mpeg_cap.crc, mpeg_cap.mpf, +			mpeg_cap.bitrate); +	} else { +		memset(&sbc_cap, 0, sizeof(sbc_cap)); + +		sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; +		sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; +		sbc_cap.channel_mode = req->sbc_capabilities.channel_mode; +		sbc_cap.frequency = req->sbc_capabilities.frequency; +		sbc_cap.allocation_method = req->sbc_capabilities.allocation_method; +		sbc_cap.subbands = req->sbc_capabilities.subbands; +		sbc_cap.block_length = req->sbc_capabilities.block_length; +		sbc_cap.min_bitpool = req->sbc_capabilities.min_bitpool; +		sbc_cap.max_bitpool = req->sbc_capabilities.max_bitpool; + +		media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, +							sizeof(sbc_cap)); + +		info("config sbc - frequency = %u channel_mode = %u " +			"allocation = %u subbands = %u blocks = %u " +			"bitpool = %u", sbc_cap.frequency, +			sbc_cap.channel_mode, sbc_cap.allocation_method, +			sbc_cap.subbands, sbc_cap.block_length, +			sbc_cap.max_bitpool); +	}  	client->caps = g_slist_append(client->caps, media_codec); | 
