linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Pali Rohár" <pali.rohar@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
Date: Wed, 19 Dec 2018 17:51:04 +0100	[thread overview]
Message-ID: <20181219165109.29088-6-pali.rohar@gmail.com> (raw)
In-Reply-To: <20181219165109.29088-1-pali.rohar@gmail.com>

Redefine bitrate field in a2dp_mpeg_t struct in endian neutral way and
separate vbr field according to A2DP specification. Define new macros
MPEG_GET_BITRATE() and MPEG_SET_BITRATE() for manipulating with bitrate
like for a2dp_aac_t struct.

And fix meaning of bitrate field. According to A2DP specification, it is
bitrate index, not bitrate itself. According to MPEG specification, each
MPEG layer have different bitrates for bitrate indexes. Therefore define
correctly bitrates for Layers 1, 2 and 3.

This fixes problems with parsing bitrate field in a2dp_mpeg_t struct as it
was broken due to endianity and it was broken for Layer 1 and 2 as bitrate
definitions was for Layer 3.
---
 profiles/audio/a2dp-codecs.h |  89 ++++++++++++++++++++++------
 tools/avinfo.c               | 135 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 172 insertions(+), 52 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 25959902c..64a09796d 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -68,22 +68,71 @@
 #define MPEG_SAMPLING_FREQ_44100	(1 << 1)
 #define MPEG_SAMPLING_FREQ_48000	1
 
-#define MPEG_BIT_RATE_VBR		0x8000
-#define MPEG_BIT_RATE_320000		0x4000
-#define MPEG_BIT_RATE_256000		0x2000
-#define MPEG_BIT_RATE_224000		0x1000
-#define MPEG_BIT_RATE_192000		0x0800
-#define MPEG_BIT_RATE_160000		0x0400
-#define MPEG_BIT_RATE_128000		0x0200
-#define MPEG_BIT_RATE_112000		0x0100
-#define MPEG_BIT_RATE_96000		0x0080
-#define MPEG_BIT_RATE_80000		0x0040
-#define MPEG_BIT_RATE_64000		0x0020
-#define MPEG_BIT_RATE_56000		0x0010
-#define MPEG_BIT_RATE_48000		0x0008
-#define MPEG_BIT_RATE_40000		0x0004
-#define MPEG_BIT_RATE_32000		0x0002
-#define MPEG_BIT_RATE_FREE		0x0001
+#define MPEG_BIT_RATE_INDEX_0		(1 << 0)
+#define MPEG_BIT_RATE_INDEX_1		(1 << 1)
+#define MPEG_BIT_RATE_INDEX_2		(1 << 2)
+#define MPEG_BIT_RATE_INDEX_3		(1 << 3)
+#define MPEG_BIT_RATE_INDEX_4		(1 << 4)
+#define MPEG_BIT_RATE_INDEX_5		(1 << 5)
+#define MPEG_BIT_RATE_INDEX_6		(1 << 6)
+#define MPEG_BIT_RATE_INDEX_7		(1 << 7)
+#define MPEG_BIT_RATE_INDEX_8		(1 << 8)
+#define MPEG_BIT_RATE_INDEX_9		(1 << 9)
+#define MPEG_BIT_RATE_INDEX_10		(1 << 10)
+#define MPEG_BIT_RATE_INDEX_11		(1 << 11)
+#define MPEG_BIT_RATE_INDEX_12		(1 << 12)
+#define MPEG_BIT_RATE_INDEX_13		(1 << 13)
+#define MPEG_BIT_RATE_INDEX_14		(1 << 14)
+
+#define MPEG_MP1_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP1_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP1_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP1_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP1_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP1_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP1_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP1_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP1_BIT_RATE_288000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP1_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP1_BIT_RATE_352000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP1_BIT_RATE_384000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP1_BIT_RATE_416000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP1_BIT_RATE_448000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_MP2_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP2_BIT_RATE_48000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP2_BIT_RATE_56000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP2_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP2_BIT_RATE_80000		MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP2_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP2_BIT_RATE_112000	MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP2_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP2_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP2_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP2_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP2_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP2_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP2_BIT_RATE_384000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_MP3_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP3_BIT_RATE_40000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP3_BIT_RATE_48000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP3_BIT_RATE_56000		MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP3_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP3_BIT_RATE_80000		MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP3_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP3_BIT_RATE_112000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP3_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP3_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP3_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP3_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP3_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP3_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_BIT_RATE_FREE		MPEG_BIT_RATE_INDEX_0
+
+#define MPEG_GET_BITRATE(a) ((uint16_t)(a).bitrate1 << 8 | (a).bitrate2)
+#define MPEG_SET_BITRATE(a, b) do { (a).bitrate1 = ((b) >> 8) & 0x7f; (a).bitrate2 = (b) & 0xff; } while (0)
 
 #define AAC_OBJECT_TYPE_MPEG2_AAC_LC	0x80
 #define AAC_OBJECT_TYPE_MPEG4_AAC_LC	0x40
@@ -168,7 +217,9 @@ typedef struct {
 	uint8_t frequency:6;
 	uint8_t mpf:1;
 	uint8_t rfa:1;
-	uint16_t bitrate;
+	uint8_t bitrate1:7;
+	uint8_t vbr:1;
+	uint8_t bitrate2;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
 typedef struct {
@@ -213,7 +264,9 @@ typedef struct {
 	uint8_t rfa:1;
 	uint8_t mpf:1;
 	uint8_t frequency:6;
-	uint16_t bitrate;
+	uint8_t vbr:1;
+	uint8_t bitrate1:7;
+	uint8_t bitrate2;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
 typedef struct {
diff --git a/tools/avinfo.c b/tools/avinfo.c
index 1f7c68d4b..ca0f12067 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -303,11 +303,15 @@ static void print_mpeg24(a2dp_aac_t *aac, uint8_t size)
 
 static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 {
+	uint16_t bitrate;
+
 	if (size < sizeof(*mpeg)) {
 		printf("\tMedia Codec: MPEG12 (broken)\n");
 		return;
 	}
 
+	bitrate = MPEG_GET_BITRATE(*mpeg);
+
 	printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: ");
 
 	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO)
@@ -343,42 +347,105 @@ static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 	if (mpeg->layer & MPEG_LAYER_MP3)
 		printf("3 ");
 
-	printf("\n\t\tBit Rate: ");
-	if (mpeg->bitrate & MPEG_BIT_RATE_FREE)
-		printf("Free format");
-	else {
-		if (mpeg->bitrate & MPEG_BIT_RATE_32000)
-			printf("32kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_40000)
-			printf("40kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_48000)
-			printf("48kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_56000)
-			printf("56kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_64000)
-			printf("64kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_80000)
-			printf("80kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_96000)
-			printf("96kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_112000)
-			printf("112kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_128000)
-			printf("128kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_160000)
-			printf("160kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_192000)
-			printf("192kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_224000)
-			printf("224kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_256000)
-			printf("256kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_320000)
-			printf("320kbps ");
+	if (bitrate & MPEG_BIT_RATE_FREE) {
+		printf("\n\t\tBit Rate: Free format");
+	} else {
+		if (mpeg->layer & MPEG_LAYER_MP1) {
+			printf("\n\t\tLayer 1 Bit Rate: ");
+			if (bitrate & MPEG_MP1_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_320000)
+				printf("320kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_352000)
+				printf("352kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_384000)
+				printf("384kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_416000)
+				printf("416kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_448000)
+				printf("448kbps ");
+		}
+
+		if (mpeg->layer & MPEG_LAYER_MP2) {
+			printf("\n\t\tLayer 2 Bit Rate: ");
+			if (bitrate & MPEG_MP2_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_48000)
+				printf("48kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_56000)
+				printf("56kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_80000)
+				printf("80kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_112000)
+				printf("112kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_320000)
+				printf("320kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_384000)
+				printf("384kbps ");
+		}
+
+		if (mpeg->layer & MPEG_LAYER_MP3) {
+			printf("\n\t\tLayer 3 Bit Rate: ");
+			if (bitrate & MPEG_MP3_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_40000)
+				printf("40kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_48000)
+				printf("48kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_56000)
+				printf("56kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_80000)
+				printf("80kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_112000)
+				printf("112kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_320000)
+				printf("320kbps ");
+		}
 	}
 
-	printf("\n\t\tVBR: %s", mpeg->bitrate & MPEG_BIT_RATE_VBR ? "Yes" :
-		"No");
+	printf("\n\t\tVBR: %s", mpeg->vbr ? "Yes" : "No");
 
 	printf("\n\t\tPayload Format: ");
 	if (mpeg->mpf)
-- 
2.11.0


  parent reply	other threads:[~2018-12-19 16:51 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
2018-12-19 16:51 ` [PATCH 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
2018-12-19 16:51 ` [PATCH 02/10] avinfo: Show Vendor Specific Data Pali Rohár
2018-12-19 16:51 ` [PATCH 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
2018-12-19 16:51 ` [PATCH 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
2018-12-19 16:51 ` Pali Rohár [this message]
2018-12-19 16:51 ` [PATCH 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
2018-12-19 16:51 ` [PATCH 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
2018-12-19 16:51 ` [PATCH 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
2018-12-19 16:51 ` [PATCH 09/10] a2dp-codecs: Add macros and structures for FastStream, aptX Low Latency and aptX HD codecs Pali Rohár
2018-12-19 16:51 ` [PATCH 10/10] avinfo: Parse information about A2DP codecs: FastStream, aptX Low Latency, aptX HD and LDAC Pali Rohár
2018-12-22 22:54 ` [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Luiz Augusto von Dentz
2018-12-23  9:30   ` Pali Rohár
2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
2018-12-23 10:40   ` [PATCH v2 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
2018-12-23 10:40   ` [PATCH v2 02/10] avinfo: Show Vendor Specific Data Pali Rohár
2018-12-23 10:40   ` [PATCH v2 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
2018-12-23 10:40   ` [PATCH v2 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
2018-12-23 10:40   ` [PATCH v2 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
2018-12-23 10:40   ` [PATCH v2 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
2018-12-23 10:40   ` [PATCH v2 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
2018-12-23 10:40   ` [PATCH v2 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
2018-12-23 10:40   ` [PATCH v2 09/10] a2dp-codecs: Add macros and structures for new codecs Pali Rohár
2018-12-23 10:40   ` [PATCH v2 10/10] avinfo: Parse new A2DP codecs Pali Rohár
2018-12-28 18:23   ` [PATCH v2 00/10] A2DP: Fix endianity and define " Luiz Augusto von Dentz
2018-12-28 18:59     ` Pali Rohár

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181219165109.29088-6-pali.rohar@gmail.com \
    --to=pali.rohar@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).