From patchwork Mon Jul 13 21:17:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Reichl X-Patchwork-Id: 11661033 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DC489722 for ; Mon, 13 Jul 2020 21:18:52 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6F7962077D for ; Mon, 13 Jul 2020 21:18:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="aFwXqEgK"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=horus.com header.i=@horus.com header.b="Bs8A1aEQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6F7962077D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=horus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id CA8FE1672; Mon, 13 Jul 2020 23:18:04 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz CA8FE1672 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1594675130; bh=sGOjC6BMu6x8LTeHIsWMHGIJmd4rJydmIQ1dRE3+dnU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=aFwXqEgKMF7u2xuWxsPjtf4CYOq4k46XEEVVMRJpBOFqKD9/025advuHbdRBc3NN/ lSMjRe9bLjHl4q/t1HK6hNoZAsDouS2R29ZHk9BzFjhvh4qPXXwNOJBZvTQF3Q9oiD y5pMrCtHElWXfxNr0J7zVCxZTHxV8bNUcwpawgOw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id DB89FF8021D; Mon, 13 Jul 2020 23:17:15 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id EAE0BF80260; Mon, 13 Jul 2020 23:17:13 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,SPF_HELO_PASS,SPF_PASS,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from mail.horus.com (mail.horus.com [78.46.148.228]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 0188DF8021D for ; Mon, 13 Jul 2020 23:17:06 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 0188DF8021D Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=horus.com header.i=@horus.com header.b="Bs8A1aEQ" Received: from lenny.lan (178-190-192-205.adsl.highway.telekom.at [178.190.192.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "E-Mail Matthias Reichl Lenny", Issuer "HiassofT CA 2014" (verified OK)) by mail.horus.com (Postfix) with ESMTPSA id 0BC026409C; Mon, 13 Jul 2020 23:17:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=horus.com; s=20180324; t=1594675025; bh=9dGOAJ8Jf6y6N0rgi1GL8exTfI2Y7e66iae2xbJ5Mx8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Bs8A1aEQ8zPcwkXhVHVExx0n6BALO6CqT5esgQMa8EBWjNb/MBG4Jb6I0PPTYeLZ+ DQDAN/wTzmz8M7hwn3brbrvviZE0CCQV8m4Hjnz3mXdDzX+xX29TdM3hEoDHTRK//E gNwY1V5utRUi5meHikNlsUfzv55/wVARwdnxUFlg= Received: by lenny.lan (Postfix, from userid 1000) id 695A52021C3; Mon, 13 Jul 2020 23:17:04 +0200 (CEST) From: Matthias Reichl To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH 1/2] pcm: iec958: implement HDMI HBR audio formatting Date: Mon, 13 Jul 2020 23:17:03 +0200 Message-Id: <20200713211704.19083-2-hias@horus.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200713211704.19083-1-hias@horus.com> References: <20200713211704.19083-1-hias@horus.com> MIME-Version: 1.0 Cc: Dom Cobley , alsa-devel@alsa-project.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" High bitrate compressed audio data like DTS HD or MAT is usually packed into 8-channel data. The HDMI specs state this has to be formatted as a single IEC958 stream, compared to normal multi- channel PCM data which has to be formatted as parallel IEC958 streams. As this single-stream formatting mode may break existing setups that expect non-PCM multichannel data to be formatted as parallel IEC958 streams it needs to be explicitly selected by setting the hdmi_mode option to true. The single-stream formatting implementation is prepared to cope with arbitrary channel counts but only limited testing was done for channel counts other than 8. Signed-off-by: Matthias Reichl --- src/pcm/pcm_iec958.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c index 76d3ca7b..17ade957 100644 --- a/src/pcm/pcm_iec958.c +++ b/src/pcm/pcm_iec958.c @@ -63,6 +63,7 @@ struct snd_pcm_iec958 { unsigned int byteswap; unsigned char preamble[3]; /* B/M/W or Z/X/Y */ snd_pcm_fast_ops_t fops; + int hdmi_mode; }; enum { PREAMBLE_Z, PREAMBLE_X, PREAMBLE_Y }; @@ -193,6 +194,10 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec, unsigned int channel; int32_t sample = 0; int counter = iec->counter; + int single_stream = iec->hdmi_mode && + (iec->status[0] & IEC958_AES0_NONAUDIO) && + (channels == 8); + int counter_step = single_stream ? ((channels + 1) >> 1) : 1; for (channel = 0; channel < channels; ++channel) { const char *src; uint32_t *dst; @@ -205,7 +210,12 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec, src_step = snd_pcm_channel_area_step(src_area); dst_step = snd_pcm_channel_area_step(dst_area) / sizeof(uint32_t); frames1 = frames; - iec->counter = counter; + + if (single_stream) + iec->counter = (counter + (channel >> 1)) % 192; + else + iec->counter = counter; + while (frames1-- > 0) { goto *get; #define GET32_END after @@ -217,9 +227,11 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec, *dst = sample; src += src_step; dst += dst_step; - iec->counter++; + iec->counter += counter_step; iec->counter %= 192; } + if (single_stream) /* set counter to ch0 value for next iteration */ + iec->counter = (counter + frames * counter_step) % 192; } } #endif /* DOC_HIDDEN */ @@ -473,6 +485,7 @@ static const snd_pcm_ops_t snd_pcm_iec958_ops = { * \param close_slave When set, the slave PCM handle is closed with copy PCM * \param status_bits The IEC958 status bits * \param preamble_vals The preamble byte values + * \param hdmi_mode When set, enable HDMI compliant formatting * \retval zero on success otherwise a negative error code * \warning Using of this function might be dangerous in the sense * of compatibility reasons. The prototype might be freely @@ -481,7 +494,8 @@ static const snd_pcm_ops_t snd_pcm_iec958_ops = { int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave, const unsigned char *status_bits, - const unsigned char *preamble_vals) + const unsigned char *preamble_vals, + int hdmi_mode) { snd_pcm_t *pcm; snd_pcm_iec958_t *iec; @@ -519,6 +533,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo memcpy(iec->preamble, preamble_vals, 3); + iec->hdmi_mode = hdmi_mode; + err = snd_pcm_new(&pcm, SND_PCM_TYPE_IEC958, name, slave->stream, slave->mode); if (err < 0) { free(iec); @@ -566,9 +582,14 @@ pcm.name { [preamble.z or preamble.b val] [preamble.x or preamble.m val] [preamble.y or preamble.w val] + [hdmi_mode true] } \endcode +When hdmi_mode is true, 8-channel compressed data is +formatted as 4 contiguous frames of a single IEC958 stream as required +by the HDMI HBR specification. + \subsection pcm_plugins_iec958_funcref Function reference
    @@ -605,6 +626,7 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, unsigned char preamble_vals[3] = { 0x08, 0x02, 0x04 /* Z, X, Y */ }; + int hdmi_mode = 0; snd_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); @@ -633,6 +655,13 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, preamble = n; continue; } + if (strcmp(id, "hdmi_mode") == 0) { + err = snd_config_get_bool(n); + if (err < 0) + continue; + hdmi_mode = err; + continue; + } SNDERR("Unknown field %s", id); return -EINVAL; } @@ -707,7 +736,7 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, return err; err = snd_pcm_iec958_open(pcmp, name, sformat, spcm, 1, status ? status_bits : NULL, - preamble_vals); + preamble_vals, hdmi_mode); if (err < 0) snd_pcm_close(spcm); return err; From patchwork Mon Jul 13 21:17:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Reichl X-Patchwork-Id: 11661035 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 74BD96C1 for ; Mon, 13 Jul 2020 21:19:41 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 06D2F2077D for ; Mon, 13 Jul 2020 21:19:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="enKh6hnv"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=horus.com header.i=@horus.com header.b="JUZX5ivR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 06D2F2077D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=horus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id DB8F584A; Mon, 13 Jul 2020 23:18:52 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DB8F584A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1594675178; bh=4KEpH69Gy0kpZKcd7UA+qynddFujiKa5MuE0r/3KbI0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=enKh6hnvjE5biAu4mMhFhVYJKyU7Ovz6IIKCJnjZEJelNPCXh2O73irJwfux+DXFW cjgNUP1RUHZapvRQPT1dW2c8kaxpJb5BSQrpEpokljzneT3DFamFgaPvA9nMG0c+BT aQvc9xYxj8W206cW22a5A6bgqEZuf1oH1nWXddQg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id A222AF80254; Mon, 13 Jul 2020 23:17:19 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 20F31F80227; Mon, 13 Jul 2020 23:17:15 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,SPF_HELO_PASS,SPF_PASS,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from mail.horus.com (mail.horus.com [78.46.148.228]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id F2A45F80116 for ; Mon, 13 Jul 2020 23:17:06 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F2A45F80116 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=horus.com header.i=@horus.com header.b="JUZX5ivR" Received: from lenny.lan (178-190-192-205.adsl.highway.telekom.at [178.190.192.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "E-Mail Matthias Reichl Lenny", Issuer "HiassofT CA 2014" (verified OK)) by mail.horus.com (Postfix) with ESMTPSA id 06CD16409B; Mon, 13 Jul 2020 23:17:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=horus.com; s=20180324; t=1594675025; bh=J+7SFZKii5BncKSfsKj7o9fv4TpKfShepnxsEnUW2/g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JUZX5ivRTXZVbq2HKp79fT9qJfltF1nb7+Yv7Clw08+LZNRzIuYbDr0LUoY/Oe366 1ZTJJ9br/OKdOOxq/M3oFQivmmK+NVxVGt9Bp4Dg0SybF1ja6ymu/CCB60Ig2HPlxh 2FCvIT8B+Iod7Wkks/gpXsqVFz46tAcZtggzhCTs= Received: by lenny.lan (Postfix, from userid 1000) id 6F1BC202270; Mon, 13 Jul 2020 23:17:04 +0200 (CEST) From: Matthias Reichl To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH 2/2] pcm: iec958: set channel status bits according to rate and format Date: Mon, 13 Jul 2020 23:17:04 +0200 Message-Id: <20200713211704.19083-3-hias@horus.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200713211704.19083-1-hias@horus.com> References: <20200713211704.19083-1-hias@horus.com> MIME-Version: 1.0 Cc: Dom Cobley , alsa-devel@alsa-project.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This mimics snd_pcm_create_iec958_consumer in the kernel. The rate and wordlength bits will only be modified if they are set to "not indicated", which is now the default if no status option is used. This allows applications to override parameters determined from the stream or implement channel status bits extensions without needing to change pcm_iec958 code. Signed-off-by: Matthias Reichl --- src/pcm/pcm_iec958.c | 80 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c index 17ade957..a11a0439 100644 --- a/src/pcm/pcm_iec958.c +++ b/src/pcm/pcm_iec958.c @@ -365,9 +365,80 @@ static int snd_pcm_iec958_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params iec->byteswap = format != SND_PCM_FORMAT_IEC958_SUBFRAME; } } - /* FIXME: needs to adjust status_bits according to the format - * and sample rate - */ + + if ((iec->status[0] & IEC958_AES0_PROFESSIONAL) == 0) { + if ((iec->status[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) { + unsigned int rate = 0; + unsigned char fs; + + err = INTERNAL(snd_pcm_hw_params_get_rate)(params, &rate, 0); + if (err < 0) + rate = 0; + + switch (rate) { + case 22050: + fs = IEC958_AES3_CON_FS_22050; + break; + case 24000: + fs = IEC958_AES3_CON_FS_24000; + break; + case 32000: + fs = IEC958_AES3_CON_FS_32000; + break; + case 44100: + fs = IEC958_AES3_CON_FS_44100; + break; + case 48000: + fs = IEC958_AES3_CON_FS_48000; + break; + case 88200: + fs = IEC958_AES3_CON_FS_88200; + break; + case 96000: + fs = IEC958_AES3_CON_FS_96000; + break; + case 176400: + fs = IEC958_AES3_CON_FS_176400; + break; + case 192000: + fs = IEC958_AES3_CON_FS_192000; + break; + case 768000: + fs = IEC958_AES3_CON_FS_768000; + break; + default: + fs = IEC958_AES3_CON_FS_NOTID; + break; + } + + iec->status[3] &= ~IEC958_AES3_CON_FS; + iec->status[3] |= fs; + } + + if ((iec->status[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) { + unsigned char ws; + switch (snd_pcm_format_width(format)) { + case 16: + ws = IEC958_AES4_CON_WORDLEN_20_16; + break; + case 18: + ws = IEC958_AES4_CON_WORDLEN_22_18; + break; + case 20: + ws = IEC958_AES4_CON_WORDLEN_20_16 | IEC958_AES4_CON_MAX_WORDLEN_24; + break; + case 24: + case 32: /* Assume 24-bit width for 32-bit samples. */ + ws = IEC958_AES4_CON_WORDLEN_24_20 | IEC958_AES4_CON_MAX_WORDLEN_24; + break; + default: + ws = IEC958_AES4_CON_WORDLEN_NOTID; + break; + } + iec->status[4] &= ~(IEC958_AES4_CON_MAX_WORDLEN_24 | IEC958_AES4_CON_WORDLEN); + iec->status[4] |= ws; + } + } return 0; } @@ -504,7 +575,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo IEC958_AES0_CON_EMPHASIS_NONE, IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER, 0, - IEC958_AES3_CON_FS_48000 + IEC958_AES3_CON_FS_NOTID, /* will be set in hwparams */ + IEC958_AES4_CON_WORDLEN_NOTID /* will be set in hwparams */ }; assert(pcmp && slave);