Re: [FFmpeg-devel] [PATCHv4] af_hdcd: more FATE tests

2016-12-28 Thread Burt P.
applied.


-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv4] af_hdcd: more FATE tests

2016-12-26 Thread Burt P
Additional/Modified FATE tests improve code coverage from 63.7% to 98.1%.

Changed fate-suite sample files:
* filter/hdcd-mix.flac (958K) added. It is a much better test than
  filter/hdcd.flac (910K), which is now unused, but can't be removed.
* filter/hdcd-fake20bit.flac (168K) added. It is the first second of
  filter/hdcd.flac, with the 16-bit LSB copied into bit 20 of a 24-bit
  stream. There isn't an actual non-16-bit HDCD sample available to test.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 tests/fate/filter-audio.mak | 84 +++--
 1 file changed, 73 insertions(+), 11 deletions(-)

diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 9c6f7cd..6de3c46 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -255,17 +255,55 @@ fate-filter-volume: CMD = md5 -i $(SRC) -af 
aperms=random,volume=precision=fixed
 fate-filter-volume: CMP = oneline
 fate-filter-volume: REF = 4d6ba75ef3e32d305d066b9bc771d6f4
 
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd
-fate-filter-hdcd: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd: CMD = md5 -i $(SRC) -af hdcd -f s24le
-fate-filter-hdcd: CMP = oneline
-fate-filter-hdcd: REF = 5db465a58d2fd0d06ca944b883b33476
-
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze
-fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f s24le
-fate-filter-hdcd-analyze: CMP = oneline
-fate-filter-hdcd-analyze: REF = 6e39dc4629c1e84321c0d8bc069b42f6
+# hdcd-mix.flac is a mix of three different sources which are interesting for 
various reasons:
+# first 5 seconds uses packet format A and max LLE of -7.0db
+# second 5 seconds uses packet format B and has a gain mismatch between 
channels
+# last 10 seconds is not HDCD but has a coincidental HDCD packet, it needs to 
be 10 seconds because it also tests the cdt expiration
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix
+fate-filter-hdcd-mix: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix: CMD = md5 -i $(SRC) -af hdcd -f s24le
+fate-filter-hdcd-mix: CMP = oneline
+fate-filter-hdcd-mix: REF = e7079913e90c124460cdbc712df5b84c
+
+# output will be different because of the gain mismatch in the second and 
third parts
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix-psoff
+fate-filter-hdcd-mix-psoff: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix-psoff: CMD = md5 -i $(SRC) -af hdcd=process_stereo=false 
-f s24le
+fate-filter-hdcd-mix-psoff: CMP = oneline
+fate-filter-hdcd-mix-psoff: REF = bd0e81fe17696b825ee3515ab928e6bb
+
+# test the different analyze modes
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-pe
+fate-filter-hdcd-analyze-pe: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-pe: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f 
s24le
+fate-filter-hdcd-analyze-pe: CMP = oneline
+fate-filter-hdcd-analyze-pe: REF = bb83e97bbd0064b9b1c0ef2f2c8f0c77
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-lle
+fate-filter-hdcd-analyze-lle: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-lle: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=lle -f 
s24le
+fate-filter-hdcd-analyze-lle: CMP = oneline
+fate-filter-hdcd-analyze-lle: REF = 121cc4a681aa0caef5c664fece7a3ddc
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-cdt
+fate-filter-hdcd-analyze-cdt: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-cdt: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=cdt -f 
s24le
+fate-filter-hdcd-analyze-cdt: CMP = oneline
+fate-filter-hdcd-analyze-cdt: REF = 12136e6a00dd532994f6edcc347af1d4
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-tgm
+fate-filter-hdcd-analyze-tgm: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-tgm: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=tgm -f 
s24le
+fate-filter-hdcd-analyze-tgm: CMP = oneline
+fate-filter-hdcd-analyze-tgm: REF = a3c39f62e9b9b42c9c440d0045d5fb2f
+# the two additional analyze modes from libhdcd
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-ltgm
+fate-filter-hdcd-analyze-ltgm: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-ltgm: CMD = md5 -i $(SRC) -af 
hdcd=analyze_mode=lle:process_stereo=false -f s24le
+fate-filter-hdcd-analyze-ltgm: CMP = oneline
+fate-filter-hdcd-analyze-ltg

Re: [FFmpeg-devel] [PATCHv3] af_hdcd: more FATE tests

2016-12-26 Thread Burt P.
On Tue, Dec 20, 2016 at 11:57 AM, Michael Niedermayer
 wrote:
> did you post links to any of the files or how can the new files be
> added ?

Yes, in IRC. Thank you for uploading.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv3] af_hdcd: more FATE tests

2016-12-19 Thread Burt P.
On Sun, Dec 18, 2016 at 6:54 PM, Michael Niedermayer
<mich...@niedermayer.cc> wrote:
> On Sun, Dec 18, 2016 at 12:48:45PM -0600, Burt P wrote:
>> Additional/Modified FATE tests improve code coverage from 63.7% to 98.1%.
>>
>> Changed fate-suite sample files:
>> * filter/hdcd-encoding-errors.flac (1.3M) replaced by
>>   a smaller version (140K). It can be replaced because the test
>>   only looks for a non-zero number of errors, so the existing test
>>   will still pass.
>
> IMO replacing files is not ok
> it would change all past instances of the related fate test
> a bug report refering to a fate failure could become unreproduceable
> or otherwise working fate tests could start failing ...
> as much as i prefer to safe a few bytes in this case i prefer to waste
> some space over the potential problems
>
> you can add files, but not remove or replace unless they are truly
> unused by every past checkout

Well, I don't mind if it is kept, I was just trying to offset the additions.
I understand why removing or replacing samples is generally not a good
idea, but I would point out that in this case, the file could be replaced
without changing the result in any past revision of the test.
This particular test outcome is determined by grepping a line out of the
log that reports the number of errors encountered, and it only has to be
non-zero, so the shorter sample with fewer errors (but at least one) still
passes any old revision.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv3] af_hdcd: more FATE tests

2016-12-18 Thread Burt P
Additional/Modified FATE tests improve code coverage from 63.7% to 98.1%.

Changed fate-suite sample files:
* filter/hdcd-encoding-errors.flac (1.3M) replaced by
  a smaller version (140K). It can be replaced because the test
  only looks for a non-zero number of errors, so the existing test
  will still pass.
* filter/hdcd-mix.flac (958K) added. It is a much better test than
  filter/hdcd.flac (910K), which is now unused, but can't be removed.
* filter/hdcd-fake20bit.flac (168K) added. It is the first second of
  filter/hdcd.flac, with the 16-bit LSB copied into bit 20 of a 24-bit
  stream. There isn't an actual non-16-bit HDCD sample available to test.
Net change -34K. Would be -944K if hdcd.flac could be removed.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 tests/fate/filter-audio.mak | 86 ++---
 1 file changed, 74 insertions(+), 12 deletions(-)

diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 9c6f7cd..b356bcc 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -255,17 +255,55 @@ fate-filter-volume: CMD = md5 -i $(SRC) -af 
aperms=random,volume=precision=fixed
 fate-filter-volume: CMP = oneline
 fate-filter-volume: REF = 4d6ba75ef3e32d305d066b9bc771d6f4
 
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd
-fate-filter-hdcd: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd: CMD = md5 -i $(SRC) -af hdcd -f s24le
-fate-filter-hdcd: CMP = oneline
-fate-filter-hdcd: REF = 5db465a58d2fd0d06ca944b883b33476
-
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze
-fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f s24le
-fate-filter-hdcd-analyze: CMP = oneline
-fate-filter-hdcd-analyze: REF = 6e39dc4629c1e84321c0d8bc069b42f6
+# hdcd-mix.flac is a mix of three different sources which are interesting for 
various reasons:
+# first 5 seconds uses packet format A and max LLE of -7.0db
+# second 5 seconds uses packet format B and has a gain mismatch between 
channels
+# last 10 seconds is not HDCD but has a coincidental HDCD packet, it needs to 
be 10 seconds because it also tests the cdt expiration
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix
+fate-filter-hdcd-mix: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix: CMD = md5 -i $(SRC) -af hdcd -f s24le
+fate-filter-hdcd-mix: CMP = oneline
+fate-filter-hdcd-mix: REF = e7079913e90c124460cdbc712df5b84c
+
+# output will be different because of the gain mismatch in the second and 
third parts
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix-psoff
+fate-filter-hdcd-mix-psoff: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix-psoff: CMD = md5 -i $(SRC) -af hdcd=process_stereo=false 
-f s24le
+fate-filter-hdcd-mix-psoff: CMP = oneline
+fate-filter-hdcd-mix-psoff: REF = bd0e81fe17696b825ee3515ab928e6bb
+
+# test the different analyze modes
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-pe
+fate-filter-hdcd-analyze-pe: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-pe: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f 
s24le
+fate-filter-hdcd-analyze-pe: CMP = oneline
+fate-filter-hdcd-analyze-pe: REF = bb83e97bbd0064b9b1c0ef2f2c8f0c77
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-lle
+fate-filter-hdcd-analyze-lle: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-lle: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=lle -f 
s24le
+fate-filter-hdcd-analyze-lle: CMP = oneline
+fate-filter-hdcd-analyze-lle: REF = 121cc4a681aa0caef5c664fece7a3ddc
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-cdt
+fate-filter-hdcd-analyze-cdt: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-cdt: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=cdt -f 
s24le
+fate-filter-hdcd-analyze-cdt: CMP = oneline
+fate-filter-hdcd-analyze-cdt: REF = 12136e6a00dd532994f6edcc347af1d4
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-tgm
+fate-filter-hdcd-analyze-tgm: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-tgm: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=tgm -f 
s24le
+fate-filter-hdcd-analyze-tgm: CMP = oneline
+fate-filter-hdcd-analyze-tgm: REF = a3c39f62e9b9b42c9c440d0045d5fb2f
+# the two additional analyze modes from libhdcd
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-ltgm
+fate-filte

[FFmpeg-devel] [PATCHv2] af_hdcd: more FATE tests

2016-12-18 Thread Burt P
Additional/Modified FATE tests improve code coverage from 63.7% to 98.1%.

Changed fate-suite sample files:
* filter/hdcd-encoding-errors.flac (1.3M) replaced by
  a smaller version (140K). It can be replaced because the test
  only looks for a non-zero number of errors, so the existing test
  will still pass.
* filter/hdcd-mix.flac (958K) added. It is a much better test than
  filter/hdcd.flac (910K), which is now unused, but can't be removed.
* filter/hdcd-fake20bit.flac (168K) added. It is the first second of
  filter/hdcd.flac, with the 16-bit LSB copied into bit 20 of a 24-bit
  stream. There isn't an actual non-16-bit HDCD sample available to test.
Net change -34K. Would be -944K if hdcd.flac could be removed.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 tests/fate/filter-audio.mak | 86 ++---
 1 file changed, 74 insertions(+), 12 deletions(-)

diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 9c6f7cd..a55e3c9 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -255,17 +255,55 @@ fate-filter-volume: CMD = md5 -i $(SRC) -af 
aperms=random,volume=precision=fixed
 fate-filter-volume: CMP = oneline
 fate-filter-volume: REF = 4d6ba75ef3e32d305d066b9bc771d6f4
 
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd
-fate-filter-hdcd: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd: CMD = md5 -i $(SRC) -af hdcd -f s24le
-fate-filter-hdcd: CMP = oneline
-fate-filter-hdcd: REF = 5db465a58d2fd0d06ca944b883b33476
-
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze
-fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f s24le
-fate-filter-hdcd-analyze: CMP = oneline
-fate-filter-hdcd-analyze: REF = 6e39dc4629c1e84321c0d8bc069b42f6
+# hdcd-mix.flac is a mix of three different sources which are interesting for 
various reasons:
+# first 5 seconds uses packet format A and max LLE of -7.0db
+# second 5 seconds uses packet format B and has a gain mismatch between 
channels
+# last 10 seconds is not HDCD but has a coincidental HDCD packet, it needs to 
be 10 seconds because it also tests the cdt expiration
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix
+fate-filter-hdcd-mix: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix: CMD = md5 -i $(SRC) -af hdcd -f s24le
+fate-filter-hdcd-mix: CMP = oneline
+fate-filter-hdcd-mix: REF = 6a3cf7f920f419477ada264cc63b40da
+
+# output will be different because of the gain mismatch in the second and 
third parts
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix-psoff
+fate-filter-hdcd-mix-psoff: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix-psoff: CMD = md5 -i $(SRC) -af hdcd=process_stereo=false 
-f s24le
+fate-filter-hdcd-mix-psoff: CMP = oneline
+fate-filter-hdcd-mix-psoff: REF = b841866d5730852256ca57564c55e0ef
+
+# test the different analyze modes
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-pe
+fate-filter-hdcd-analyze-pe: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-pe: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f 
s24le
+fate-filter-hdcd-analyze-pe: CMP = oneline
+fate-filter-hdcd-analyze-pe: REF = 9ddd10dfea756160456e25dd96a752b8
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-lle
+fate-filter-hdcd-analyze-lle: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-lle: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=lle -f 
s24le
+fate-filter-hdcd-analyze-lle: CMP = oneline
+fate-filter-hdcd-analyze-lle: REF = be353f79d3e653d658a6e6e99d7655c8
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-cdt
+fate-filter-hdcd-analyze-cdt: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-cdt: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=cdt -f 
s24le
+fate-filter-hdcd-analyze-cdt: CMP = oneline
+fate-filter-hdcd-analyze-cdt: REF = d828abe932e0d2bfc914eaa23c15b7f6
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-tgm
+fate-filter-hdcd-analyze-tgm: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-tgm: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=tgm -f 
s24le
+fate-filter-hdcd-analyze-tgm: CMP = oneline
+fate-filter-hdcd-analyze-tgm: REF = 407ed0dc8c6fd17cc8c0b53a8b2b0e34
+# the two additional analyze modes from libhdcd
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-ltgm
+fate-filte

Re: [FFmpeg-devel] [PATCH] af_hdcd: more FATE tests

2016-12-18 Thread Burt P.
On Sun, Dec 18, 2016 at 3:30 AM, Hendrik Leppkes <h.lepp...@gmail.com> wrote:
> On Sun, Dec 18, 2016 at 8:42 AM, Burt P <pbu...@gmail.com> wrote:
>> Additional/Modified FATE tests improve code coverage from 63.7% to 98.1%.
>>
>> Changed fate-suite sample files:
>> * filter/hdcd-encoding-errors.flac (1.3M) replaced by
>>   filter/hdcd-encoding-errors2.flac (140K)
>> * filter/hdcd-mix.flac (2.2M) added
>> * filter/hdcd-fake20bit.flac (168K) added
>> * filter/hdcd.flac (910K) removed, although it was a nice tune and
>>   the samples that replace it are terrible sounds.
>> Net change +290K.
>>
>
> We cannot delete samples because that would break old versions of FATE
> (which is vital for bisecting etc), so knowing and accounting for
> that, would that change any of these choices to add/remove samples?
> Because the net change goes to around +2.5M without any removals.
>

Well, hdcd-encoding-errors2.flac could simply be named
hdcd-encoding-errors.flac and it should not affect the test that uses it,
even in an old version. There only needs to be a non-zero number of
errors, 2 is as good as 4.

The sample hdcd.flac is a nice sound, but it isn't a very interesting
example of HDCD for testing. hdcd-mix.flac is a concatenation of three
different samples, each one interesting in a different way, and it does
quite a bit for code coverage. I will, however, try to make it smaller.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd: more FATE tests

2016-12-17 Thread Burt P
Additional/Modified FATE tests improve code coverage from 63.7% to 98.1%.

Changed fate-suite sample files:
* filter/hdcd-encoding-errors.flac (1.3M) replaced by
  filter/hdcd-encoding-errors2.flac (140K)
* filter/hdcd-mix.flac (2.2M) added
* filter/hdcd-fake20bit.flac (168K) added
* filter/hdcd.flac (910K) removed, although it was a nice tune and
  the samples that replace it are terrible sounds.
Net change +290K.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 tests/fate/filter-audio.mak | 86 ++---
 1 file changed, 74 insertions(+), 12 deletions(-)

diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 9c6f7cd..a55e3c9 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -255,17 +255,55 @@ fate-filter-volume: CMD = md5 -i $(SRC) -af 
aperms=random,volume=precision=fixed
 fate-filter-volume: CMP = oneline
 fate-filter-volume: REF = 4d6ba75ef3e32d305d066b9bc771d6f4
 
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd
-fate-filter-hdcd: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd: CMD = md5 -i $(SRC) -af hdcd -f s24le
-fate-filter-hdcd: CMP = oneline
-fate-filter-hdcd: REF = 5db465a58d2fd0d06ca944b883b33476
-
-FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze
-fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
-fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f s24le
-fate-filter-hdcd-analyze: CMP = oneline
-fate-filter-hdcd-analyze: REF = 6e39dc4629c1e84321c0d8bc069b42f6
+# hdcd-mix.flac is a mix of three different sources which are interesting for 
various reasons:
+# first 5 seconds uses packet format A and max LLE of -7.0db
+# second 5 seconds uses packet format B and has a gain mismatch between 
channels
+# last 10 seconds is not HDCD but has a coincidental HDCD packet, it needs to 
be 10 seconds because it also tests the cdt expiration
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix
+fate-filter-hdcd-mix: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix: CMD = md5 -i $(SRC) -af hdcd -f s24le
+fate-filter-hdcd-mix: CMP = oneline
+fate-filter-hdcd-mix: REF = 6a3cf7f920f419477ada264cc63b40da
+
+# output will be different because of the gain mismatch in the second and 
third parts
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-mix-psoff
+fate-filter-hdcd-mix-psoff: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-mix-psoff: CMD = md5 -i $(SRC) -af hdcd=process_stereo=false 
-f s24le
+fate-filter-hdcd-mix-psoff: CMP = oneline
+fate-filter-hdcd-mix-psoff: REF = b841866d5730852256ca57564c55e0ef
+
+# test the different analyze modes
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-pe
+fate-filter-hdcd-analyze-pe: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-pe: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f 
s24le
+fate-filter-hdcd-analyze-pe: CMP = oneline
+fate-filter-hdcd-analyze-pe: REF = 9ddd10dfea756160456e25dd96a752b8
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-lle
+fate-filter-hdcd-analyze-lle: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-lle: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=lle -f 
s24le
+fate-filter-hdcd-analyze-lle: CMP = oneline
+fate-filter-hdcd-analyze-lle: REF = be353f79d3e653d658a6e6e99d7655c8
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-cdt
+fate-filter-hdcd-analyze-cdt: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-cdt: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=cdt -f 
s24le
+fate-filter-hdcd-analyze-cdt: CMP = oneline
+fate-filter-hdcd-analyze-cdt: REF = d828abe932e0d2bfc914eaa23c15b7f6
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-tgm
+fate-filter-hdcd-analyze-tgm: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-tgm: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=tgm -f 
s24le
+fate-filter-hdcd-analyze-tgm: CMP = oneline
+fate-filter-hdcd-analyze-tgm: REF = 407ed0dc8c6fd17cc8c0b53a8b2b0e34
+# the two additional analyze modes from libhdcd
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze-ltgm
+fate-filter-hdcd-analyze-ltgm: SRC = $(TARGET_SAMPLES)/filter/hdcd-mix.flac
+fate-filter-hdcd-analyze-ltgm: CMD = md5 -i $(SRC) -af 
hdcd=analyze_mode=lle:process_stereo=false -f s24le
+fate-filter-hdcd-analyze-ltgm: CMP = oneline
+fate-filter-hdcd-analyze-ltgm: REF = 276a354519a15d1c83c5ca394fe5dffc
+FATE_AFILTER_S

Re: [FFmpeg-devel] [PATCH 5/5] af_hdcd: add experimental 20 and 24-bit decoding support

2016-10-05 Thread Burt P.
applied

split into two commits

--
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 3/5] af_hdcd: add mono as a supported channel layout

2016-10-05 Thread Burt P.
applied

--
Burt

On Sun, Oct 2, 2016 at 2:46 AM, Burt P <pbu...@gmail.com> wrote:
> Signed-off-by: Burt P <pbu...@gmail.com>
> ---
>  libavfilter/af_hdcd.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
> index 90b6b64..6f35c09 100644
> --- a/libavfilter/af_hdcd.c
> +++ b/libavfilter/af_hdcd.c
> @@ -1724,6 +1724,9 @@ static int query_formats(AVFilterContext *ctx)
>  };
>  int ret;
>
> +ret = ff_add_channel_layout(, AV_CH_LAYOUT_MONO);
> +if (ret < 0)
> +return ret;
>  ret = ff_add_channel_layout(, AV_CH_LAYOUT_STEREO);
>  if (ret < 0)
>  return ret;
> @@ -1822,7 +1825,7 @@ static int config_input(AVFilterLink *inlink) {
>  s->cdt_ms, s->state[0].sustain_reset );
>
>  if (inlink->channels != 2 && s->process_stereo) {
> -av_log(ctx, AV_LOG_WARNING, "process_stereo disabled (channels = 
> %d)", inlink->channels);
> +av_log(ctx, AV_LOG_WARNING, "process_stereo disabled (channels = 
> %d)\n", inlink->channels);
>  s->process_stereo = 0;
>  }
>  av_log(ctx, AV_LOG_VERBOSE, "Process mode: %s\n",
> --
> 2.7.4
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 4/5] af_hdcd: hdcd_scan() and hdcd_integrate() handle stereo and single channel

2016-10-05 Thread Burt P.
applied

--
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/5] af_hdcd: allow all HDCD sample rates

2016-10-05 Thread Burt P.
applied

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/5] af_hdcd: support s16p (WavPack) directly

2016-10-02 Thread Burt P
The buffer is already being copied anyway, so interlace the planar
format during the copy and remove one use of auto-convert.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index a9f2f93..90b6b64 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1665,10 +1665,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 }
 out->format = outlink->format; // is this needed?
 
-in_data  = (int16_t*)in->data[0];
 out_data = (int32_t*)out->data[0];
-for (c = n = 0; n < in->nb_samples * in->channels; n++)
-out_data[n] = in_data[n];
+if (inlink->format == AV_SAMPLE_FMT_S16P) {
+for (n = 0; n < in->nb_samples; n++)
+for (c = 0; c < in->channels; c++) {
+in_data = (int16_t*)in->extended_data[c];
+out_data[(n * in->channels) + c] = in_data[n];
+}
+} else {
+in_data  = (int16_t*)in->data[0];
+for (n = 0; n < in->nb_samples * in->channels; n++)
+out_data[n] = in_data[n];
+}
 
 if (s->process_stereo) {
 hdcd_detect_start(>detect);
@@ -1707,6 +1715,7 @@ static int query_formats(AVFilterContext *ctx)
 
 static const enum AVSampleFormat sample_fmts_in[] = {
 AV_SAMPLE_FMT_S16,
+AV_SAMPLE_FMT_S16P,
 AV_SAMPLE_FMT_NONE
 };
 static const enum AVSampleFormat sample_fmts_out[] = {
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] Alternate HDCD format/rate support

2016-10-02 Thread Burt P
According to the Users' Manual, the PM Model Two would encode 
HDCD in any CD or DVD-Audio sampler rates, and at 16, 20, or 
24-bit output. While HDCD was (afaik) only published on CD, and
therefor 16-bit@44100Hz, audio may exist in any other other formats
supported by the encoding equipment, so I've made an effort support them.

At the end of this set, auto-convert is disabled, as now the filter will
handle any format that might ligitimately have HDCD encoding. This was
requested by Nicolas George in an earlier conversation referenced in the
last patch's commit message.

Thanks for comments.
---
Burt


___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/5] af_hdcd: allow all HDCD sample rates

2016-10-02 Thread Burt P
The PM Model Two could output HDCD-encoded audio in CD and all
DVD-Audio sample rates. (44100, 48000, 88200, 96000, 176400, and
192000 Hz)

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 40dba3c..a9f2f93 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1693,9 +1693,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 
 static int query_formats(AVFilterContext *ctx)
 {
+static const int sample_rates[] = {
+44100, 48000,
+88200, 96000,
+176400, 192000,
+-1
+};
 AVFilterFormats *in_formats;
 AVFilterFormats *out_formats;
-AVFilterFormats *sample_rates = NULL;
 AVFilterChannelLayouts *layouts = NULL;
 AVFilterLink *inlink  = ctx->inputs[0];
 AVFilterLink *outlink = ctx->outputs[0];
@@ -1730,11 +1735,8 @@ static int query_formats(AVFilterContext *ctx)
 if (ret < 0)
 return ret;
 
-ret = ff_add_format(_rates, 44100);
-if (ret < 0)
-return AVERROR(ENOMEM);
-
-return ff_set_common_samplerates(ctx, sample_rates);
+return
+ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates) );
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/5] af_hdcd: hdcd_analyze_gen() using int instead of float

2016-09-07 Thread Burt P.
applied

as is for now.

Thanks for the comment. I will look into a faster way of doing it.
I only needed to change from the float version because it was giving
different results for i686 than for amd64.
I don't know why, exactly, but I do know that this version gives
bit-perfect results everywhere I've tried it.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/5] af_hdcd: some types renamed to remove _t

2016-09-07 Thread Burt P.
applied

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 3/5] af_hdcd: fix possible integer overflow

2016-09-07 Thread Burt P.
applied

with fix:
uint64_t sustain_reset = (uint64_t)cdt_ms * rate / 1000;

Thank you, Michael.

-- 
Burt

On Tue, Sep 6, 2016 at 5:00 PM, Michael Niedermayer
<mich...@niedermayer.cc> wrote:
> On Mon, Sep 05, 2016 at 06:18:43AM -0500, Burt P wrote:
>> Signed-off-by: Burt P <pbu...@gmail.com>
>> ---
>>  libavfilter/af_hdcd.c | 9 -
>>  1 file changed, 4 insertions(+), 5 deletions(-)
>>
>> diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
>> index c8bda82..c249589 100644
>> --- a/libavfilter/af_hdcd.c
>> +++ b/libavfilter/af_hdcd.c
>> @@ -1004,16 +1004,15 @@ AVFILTER_DEFINE_CLASS(hdcd);
>>  static void hdcd_reset(hdcd_state *state, unsigned rate, unsigned cdt_ms)
>>  {
>>  int i;
>> +uint64_t sustain_reset = cdt_ms * rate / 1000;
>
> this can still overflow
> cdt_ms and rate are 32bit their product is 32bit divided by 1000
> its around 22 bit, the 64bit is too late
>
>
>>
>>  state->window = 0;
>>  state->readahead = 32;
>>  state->arg = 0;
>>  state->control = 0;
>> -
>>  state->running_gain = 0;
>> -
>> +state->sustain_reset = sustain_reset;
>>  state->sustain = 0;
>> -state->sustain_reset = cdt_ms*rate/1000;
>
> [...]
>
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> The worst form of inequality is to try to make unequal things equal.
> -- Aristotle
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 4/5] af_hdcd: move decoding setup from init to config_input

2016-09-07 Thread Burt P.
applied

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 5/5] af_hdcd: tweak hdcd_analyze_prepare() a bit

2016-09-07 Thread Burt P.
applied

On Mon, Sep 5, 2016 at 6:18 AM, Burt P <pbu...@gmail.com> wrote:
> * use the actual sample rate
> * use a more sensible frequency for the tone
> * update fate test result
>
> Signed-off-by: Burt P <pbu...@gmail.com>
> ---
>  libavfilter/af_hdcd.c   | 9 ++---
>  tests/fate/filter-audio.mak | 2 +-
>  2 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
> index 1487a0b..fde6b7b 100644
> --- a/libavfilter/af_hdcd.c
> +++ b/libavfilter/af_hdcd.c
> @@ -871,6 +871,7 @@ typedef struct {
>   *  a code. -1 for timer never set. */
>  int count_sustain_expired;
>
> +int rate;   /**< sampling rate */
>  int _ana_snb;   /**< used in the analyze mode tone generator 
> */
>  } hdcd_state;
>
> @@ -1026,6 +1027,7 @@ static void hdcd_reset(hdcd_state *state, unsigned 
> rate, unsigned cdt_ms)
>  state->max_gain = 0;
>  state->count_sustain_expired = -1;
>
> +state->rate = rate;
>  state->_ana_snb = 0;
>  }
>
> @@ -1297,7 +1299,8 @@ static int hdcd_scan_stereo(HDCDContext *ctx, const 
> int32_t *samples, int max)
>
>  /** replace audio with solid tone, but save LSBs */
>  static void hdcd_analyze_prepare(hdcd_state *state, int32_t *samples, int 
> count, int stride) {
> -int n;
> +int n, f = 300;
> +int so = state->rate / f;
>  for (n = 0; n < count * stride; n += stride) {
>  /* in analyze mode, the audio is replaced by a solid tone, and
>   * amplitude is changed to signal when the specified feature is
> @@ -1306,9 +1309,9 @@ static void hdcd_analyze_prepare(hdcd_state *state, 
> int32_t *samples, int count,
>   * bit 1: Original sample was above PE level */
>  int32_t save = (abs(samples[n]) - PEAK_EXT_LEVEL >= 0) ? 2 : 0; /* 
> above PE level */
>  save |= samples[n] & 1;  /* save LSB for HDCD 
> packets */
> -samples[n] = TONEGEN16(state->_ana_snb, 277.18, 44100, 0.1);
> +samples[n] = TONEGEN16(state->_ana_snb, f, state->rate, 0.1);
>  samples[n] = (samples[n] | 3) ^ ((~save) & 3);
> -if (++state->_ana_snb > 0x3fff) state->_ana_snb = 0;
> +if (++state->_ana_snb > so) state->_ana_snb = 0;
>  }
>  }
>
> diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
> index 2066fa9..cf92ef6 100644
> --- a/tests/fate/filter-audio.mak
> +++ b/tests/fate/filter-audio.mak
> @@ -242,7 +242,7 @@ FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, 
> FLAC, FLAC, PCM_S24LE, PCM
>  fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
>  fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f 
> s24le
>  fate-filter-hdcd-analyze: CMP = oneline
> -fate-filter-hdcd-analyze: REF = 81a4f00f85a585bc0198e9a0670a8cde
> +fate-filter-hdcd-analyze: REF = 6e39dc4629c1e84321c0d8bc069b42f6
>
>  FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
> PCM_S24LE) += fate-filter-hdcd-false-positive
>  fate-filter-hdcd-false-positive: SRC = 
> $(TARGET_SAMPLES)/filter/hdcd-false-positive.flac
> --
> 2.7.4
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 5/5] af_hdcd: tweak hdcd_analyze_prepare() a bit

2016-09-06 Thread Burt P.
On Tue, Sep 6, 2016 at 6:12 AM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:
> 2016-09-06 13:02 GMT+02:00 Burt P. <pbu...@gmail.com>:
>> On Tue, Sep 6, 2016 at 5:22 AM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:
>>> 2016-09-05 13:18 GMT+02:00 Burt P <pbu...@gmail.com>:
>>>> * use the actual sample rate
>>>
>>> Is hdcd supposed to work for sample_rates
>>> different from 44100?
>>
>> As I understand it, yes. The PM Model 2 supported code
>> insertion at all CD and DVD-Audio sample rates, so:
>> 44.1, 48, 88.2, 96, 176.4, and 192 kHz.
>> If any DVD-Audio was ever actually released with HDCD
>> encoding, I do not know.
>
> Is there a test if the sample_rate is any of the above?
>

Right now, query_formats only accepts 44100. I don't have any higher
rate samples to test, I don't know if it is a good idea to just add
the other rates to the accepted list if I can't test the results.
In this patch, I took the opportunity to remove a hard-coded rate and
use one from the framework. I did the same in patch 4/5 in this set.
hdcd_reset() already uses a variable rate to set the cdt period. All
that is left is to make whatever changes to hdcd_envelope(), if any.
So, perhaps in the future it will be possible to support the higher
rates.

I don't have any HDCD-encoded DVD-Audio (or any DVD-Audio), and I also
don't have a PM Model Two to generate some. For now anyway, I can't
test it.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 5/5] af_hdcd: tweak hdcd_analyze_prepare() a bit

2016-09-06 Thread Burt P.
On Tue, Sep 6, 2016 at 5:22 AM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:
> 2016-09-05 13:18 GMT+02:00 Burt P <pbu...@gmail.com>:
>> * use the actual sample rate
>
> Is hdcd supposed to work for sample_rates
> different from 44100?

As I understand it, yes. The PM Model 2 supported code insertion at
all CD and DVD-Audio sample rates, so:
44.1, 48, 88.2, 96, 176.4, and 192 kHz.
If any DVD-Audio was ever actually released with HDCD encoding, I do not know.

>> * use a more sensible frequency for the tone
>> * update fate test result
>
> Can't this be split?

It could, if you would like it to be.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/5] af_hdcd: fix possible integer overflow

2016-09-05 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index c8bda82..c249589 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1004,16 +1004,15 @@ AVFILTER_DEFINE_CLASS(hdcd);
 static void hdcd_reset(hdcd_state *state, unsigned rate, unsigned cdt_ms)
 {
 int i;
+uint64_t sustain_reset = cdt_ms * rate / 1000;
 
 state->window = 0;
 state->readahead = 32;
 state->arg = 0;
 state->control = 0;
-
 state->running_gain = 0;
-
+state->sustain_reset = sustain_reset;
 state->sustain = 0;
-state->sustain_reset = cdt_ms*rate/1000;
 
 state->code_counterA = 0;
 state->code_counterA_almost = 0;
@@ -1788,8 +1787,8 @@ static av_cold int init(AVFilterContext *ctx)
 hdcd_reset(>state[c], 44100, s->cdt_ms);
 }
 
-av_log(ctx, AV_LOG_VERBOSE, "CDT period: %dms (%d samples @44100Hz)\n",
-s->cdt_ms, s->cdt_ms*44100/1000 );
+av_log(ctx, AV_LOG_VERBOSE, "CDT period: %dms (%u samples @44100Hz)\n",
+s->cdt_ms, s->state[0].sustain_reset );
 av_log(ctx, AV_LOG_VERBOSE, "Process mode: %s\n",
 (s->process_stereo) ? "process stereo channels together" : "process 
each channel separately");
 av_log(ctx, AV_LOG_VERBOSE, "Force PE: %s\n",
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/5] af_hdcd: some types renamed to remove _t

2016-09-05 Thread Burt P
Following a suggestion by Diego Biurrun.
_t is reserved for POSIX, apparently.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 58 +--
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 0272305..cde2340 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -872,13 +872,13 @@ typedef struct {
 int count_sustain_expired;
 
 int _ana_snb;   /**< used in the analyze mode tone generator */
-} hdcd_state_t;
+} hdcd_state;
 
 typedef enum {
 HDCD_PE_NEVER= 0, /**< All valid packets have PE set to off */
 HDCD_PE_INTERMITTENT = 1, /**< Some valid packets have PE set to on */
 HDCD_PE_PERMANENT= 2, /**< All valid packets have PE set to on  */
-} hdcd_pe_t;
+} hdcd_pe;
 
 static const char * const pe_str[] = {
 "never enabled",
@@ -890,31 +890,31 @@ typedef enum {
 HDCD_NONE= 0,  /**< HDCD packets do not (yet) appear  */
 HDCD_NO_EFFECT   = 1,  /**< HDCD packets appear, but all control codes 
are NOP */
 HDCD_EFFECTUAL   = 2,  /**< HDCD packets appear, and change the output 
in some way */
-} hdcd_detection_t;
+} hdcd_dv;
 
 typedef enum {
 HDCD_PVER_NONE   = 0, /**< No packets (yet) discovered */
 HDCD_PVER_A  = 1, /**< Packets of type A (8-bit control) 
discovered */
 HDCD_PVER_B  = 2, /**< Packets of type B (8-bit control, 8-bit 
XOR) discovered */
 HDCD_PVER_MIX= 3, /**< Packets of type A and B discovered, most 
likely an encoding error */
-} hdcd_pf_t;
+} hdcd_pf;
 
 static const char * const pf_str[] = {
 "?", "A", "B", "A+B"
 };
 
 typedef struct {
-hdcd_detection_t hdcd_detected;
-hdcd_pf_t packet_type;
+hdcd_dv hdcd_detected;
+hdcd_pf packet_type;
 int total_packets; /**< valid packets */
 int errors;/**< detectable errors */
-hdcd_pe_t peak_extend;
+hdcd_pe peak_extend;
 int uses_transient_filter;
 float max_gain_adjustment; /**< in dB, expected in the range -7.5 to 0.0 */
 int cdt_expirations;   /**< -1 for never set, 0 for set but never 
expired */
 
 int _active_count; /**< used internally */
-} hdcd_detection_data_t;
+} hdcd_detection_data;
 
 typedef enum {
 HDCD_ANA_OFF= 0,
@@ -923,7 +923,7 @@ typedef enum {
 HDCD_ANA_CDT= 3,
 HDCD_ANA_TGM= 4,
 HDCD_ANA_TOP= 5, /**< used in max value of AVOption */
-} hdcd_ana_mode_t;
+} hdcd_ana_mode;
 
 /** analyze mode descriptions: macro for AVOption definitions, array of const 
char for mapping mode to string */
 #define HDCD_ANA_OFF_DESC "disabled"
@@ -941,7 +941,7 @@ static const char * const ana_mode_str[] = {
 
 typedef struct HDCDContext {
 const AVClass *class;
-hdcd_state_t state[HDCD_MAX_CHANNELS];
+hdcd_state state[HDCD_MAX_CHANNELS];
 
 /* AVOption members */
 /** use hdcd_*_stereo() functions to process both channels together.
@@ -975,7 +975,7 @@ typedef struct HDCDContext {
 int val_target_gain;   /**< last matching target_gain in both channels */
 
 /* User information/stats */
-hdcd_detection_data_t detect;
+hdcd_detection_data detect;
 } HDCDContext;
 
 #define OFFSET(x) offsetof(HDCDContext, x)
@@ -1001,7 +1001,7 @@ static const AVOption hdcd_options[] = {
 
 AVFILTER_DEFINE_CLASS(hdcd);
 
-static void hdcd_reset(hdcd_state_t *state, unsigned rate, unsigned cdt_ms)
+static void hdcd_reset(hdcd_state *state, unsigned rate, unsigned cdt_ms)
 {
 int i;
 
@@ -1031,7 +1031,7 @@ static void hdcd_reset(hdcd_state_t *state, unsigned 
rate, unsigned cdt_ms)
 }
 
 /** update the user info/counters */
-static void hdcd_update_info(hdcd_state_t *state)
+static void hdcd_update_info(hdcd_state *state)
 {
 if (state->control & 16) state->count_peak_extend++;
 if (state->control & 32) state->count_transient_filter++;
@@ -1047,9 +1047,9 @@ typedef enum {
 HDCD_CODE_B_CHECKFAIL,
 HDCD_CODE_EXPECT_A,
 HDCD_CODE_EXPECT_B,
-} hdcd_code_result_t;
+} hdcd_code_result;
 
-static hdcd_code_result_t hdcd_code(const uint32_t bits, unsigned char *code)
+static hdcd_code_result hdcd_code(const uint32_t bits, unsigned char *code)
 {
 if ((bits & 0x0fa00500) == 0x0fa00500) {
 /* A: 8-bit code  0x7e0fa005[..] */
@@ -1078,7 +1078,7 @@ static hdcd_code_result_t hdcd_code(const uint32_t bits, 
unsigned char *code)
 return HDCD_CODE_NONE;
 }
 
-static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t *state, int *flag, 
const int32_t *samples, int count, int stride)
+static int hdcd_integrate(HDCDContext *ctx, hdcd_state *state, int *flag, 
const int32_t *samples, int count, int stride)
 {
 uint32_t bits = 0;
 int result = FFMIN(state->readahead, count);
@@ -1213,7 +1

[FFmpeg-devel] [PATCH 4/5] af_hdcd: move decoding setup from init to config_input

2016-09-05 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 40 +---
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index c249589..1487a0b 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1776,31 +1776,15 @@ static av_cold void uninit(AVFilterContext *ctx)
 static av_cold int init(AVFilterContext *ctx)
 {
 HDCDContext *s = ctx->priv;
-int c;
 
 s->sample_count = 0;
 s->fctx = ctx;
 s->bad_config = 0;
 
-hdcd_detect_reset(>detect);
-for (c = 0; c < HDCD_MAX_CHANNELS; c++) {
-hdcd_reset(>state[c], 44100, s->cdt_ms);
-}
-
-av_log(ctx, AV_LOG_VERBOSE, "CDT period: %dms (%u samples @44100Hz)\n",
-s->cdt_ms, s->state[0].sustain_reset );
-av_log(ctx, AV_LOG_VERBOSE, "Process mode: %s\n",
-(s->process_stereo) ? "process stereo channels together" : "process 
each channel separately");
-av_log(ctx, AV_LOG_VERBOSE, "Force PE: %s\n",
-(s->force_pe) ? "on" : "off");
-av_log(ctx, AV_LOG_VERBOSE, "Analyze mode: [%d] %s\n",
-s->analyze_mode, ana_mode_str[s->analyze_mode] );
-if (s->disable_autoconvert)
+if (s->disable_autoconvert) {
+av_log(ctx, AV_LOG_VERBOSE, "Disabling automatic format 
conversion.\n");
 avfilter_graph_set_auto_convert(ctx->graph, 
AVFILTER_AUTO_CONVERT_NONE);
-av_log(ctx, AV_LOG_VERBOSE, "Auto-convert: %s (requested: %s)\n",
-(ctx->graph->disable_auto_convert) ? "disabled" : "enabled",
-(s->disable_autoconvert) ? "disable" : "do not disable" );
-
+}
 return 0;
 }
 
@@ -1808,11 +1792,29 @@ static int config_input(AVFilterLink *inlink) {
 AVFilterContext *ctx = inlink->dst;
 HDCDContext *s = ctx->priv;
 AVFilterLink *lk;
+int c;
+
+av_log(ctx, AV_LOG_VERBOSE, "Auto-convert: %s\n",
+(ctx->graph->disable_auto_convert) ? "disabled" : "enabled");
+
+hdcd_detect_reset(>detect);
+for (c = 0; c < HDCD_MAX_CHANNELS; c++) {
+hdcd_reset(>state[c], inlink->sample_rate, s->cdt_ms);
+}
+av_log(ctx, AV_LOG_VERBOSE, "CDT period: %dms (%u samples @44100Hz)\n",
+s->cdt_ms, s->state[0].sustain_reset );
 
 if (inlink->channels != 2 && s->process_stereo) {
 av_log(ctx, AV_LOG_WARNING, "process_stereo disabled (channels = %d)", 
inlink->channels);
 s->process_stereo = 0;
 }
+av_log(ctx, AV_LOG_VERBOSE, "Process mode: %s\n",
+(s->process_stereo) ? "process stereo channels together" : "process 
each channel separately");
+
+av_log(ctx, AV_LOG_VERBOSE, "Force PE: %s\n",
+(s->force_pe) ? "on" : "off");
+av_log(ctx, AV_LOG_VERBOSE, "Analyze mode: [%d] %s\n",
+s->analyze_mode, ana_mode_str[s->analyze_mode] );
 
 lk = inlink;
 while(lk != NULL) {
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 5/5] af_hdcd: tweak hdcd_analyze_prepare() a bit

2016-09-05 Thread Burt P
* use the actual sample rate
* use a more sensible frequency for the tone
* update fate test result

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c   | 9 ++---
 tests/fate/filter-audio.mak | 2 +-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 1487a0b..fde6b7b 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -871,6 +871,7 @@ typedef struct {
  *  a code. -1 for timer never set. */
 int count_sustain_expired;
 
+int rate;   /**< sampling rate */
 int _ana_snb;   /**< used in the analyze mode tone generator */
 } hdcd_state;
 
@@ -1026,6 +1027,7 @@ static void hdcd_reset(hdcd_state *state, unsigned rate, 
unsigned cdt_ms)
 state->max_gain = 0;
 state->count_sustain_expired = -1;
 
+state->rate = rate;
 state->_ana_snb = 0;
 }
 
@@ -1297,7 +1299,8 @@ static int hdcd_scan_stereo(HDCDContext *ctx, const 
int32_t *samples, int max)
 
 /** replace audio with solid tone, but save LSBs */
 static void hdcd_analyze_prepare(hdcd_state *state, int32_t *samples, int 
count, int stride) {
-int n;
+int n, f = 300;
+int so = state->rate / f;
 for (n = 0; n < count * stride; n += stride) {
 /* in analyze mode, the audio is replaced by a solid tone, and
  * amplitude is changed to signal when the specified feature is
@@ -1306,9 +1309,9 @@ static void hdcd_analyze_prepare(hdcd_state *state, 
int32_t *samples, int count,
  * bit 1: Original sample was above PE level */
 int32_t save = (abs(samples[n]) - PEAK_EXT_LEVEL >= 0) ? 2 : 0; /* 
above PE level */
 save |= samples[n] & 1;  /* save LSB for HDCD 
packets */
-samples[n] = TONEGEN16(state->_ana_snb, 277.18, 44100, 0.1);
+samples[n] = TONEGEN16(state->_ana_snb, f, state->rate, 0.1);
 samples[n] = (samples[n] | 3) ^ ((~save) & 3);
-if (++state->_ana_snb > 0x3fff) state->_ana_snb = 0;
+if (++state->_ana_snb > so) state->_ana_snb = 0;
 }
 }
 
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 2066fa9..cf92ef6 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -242,7 +242,7 @@ FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, 
FLAC, PCM_S24LE, PCM
 fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
 fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f s24le
 fate-filter-hdcd-analyze: CMP = oneline
-fate-filter-hdcd-analyze: REF = 81a4f00f85a585bc0198e9a0670a8cde
+fate-filter-hdcd-analyze: REF = 6e39dc4629c1e84321c0d8bc069b42f6
 
 FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-false-positive
 fate-filter-hdcd-false-positive: SRC = 
$(TARGET_SAMPLES)/filter/hdcd-false-positive.flac
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 0/5] af_hdcd changes

2016-09-05 Thread Burt P
Hi. Patches follow.

--
Burt

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv2] af_hdcd: for easier maintenance alongside libhdcd

2016-08-25 Thread Burt P.
applied

--
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 3/3] af_hdcd: for easier maintenance alongside libhdcd

2016-08-25 Thread Burt P.
Thanks for looking at it.


On Wed, Aug 24, 2016 at 1:06 PM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:
> Hi!
>
> 2016-08-24 16:38 GMT+02:00 Burt P. <pbu...@gmail.com>:
>> On Tue, Aug 23, 2016 at 2:29 PM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:
>>> It seems safer to me to use the actual number of channels than the
>>> channel layout.
>>
>> Alright, new patch version incoming.
>
> No more comments from me.
> (I hope you tested it...)
>
> Thank you, Carl Eugen
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 3/3] af_hdcd: for easier maintenance alongside libhdcd

2016-08-24 Thread Burt P.
On Tue, Aug 23, 2016 at 2:29 PM, Carl Eugen Hoyos  wrote:
> It seems safer to me to use the actual number of channels than the
> channel layout.

Alright, new patch version incoming.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv2] af_hdcd: for easier maintenance alongside libhdcd

2016-08-24 Thread Burt P
Mostly just re-arranges some code to make it easier to update this
filter and libhdcd together. filter_frame() is much simpler as a
result.

* use the HDCD detection data structure and functions from libhdcd,
  moved detection code out of filter_frame()
* moved analyze_mode preparation out of filter_frame() into
  hdcd_analyze_prepare(), from libhdcd
* moved some macro definitions to the top so they are all together

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 271 --
 1 file changed, 172 insertions(+), 99 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 2324dc3..0360bc9 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -823,6 +823,20 @@ static const int32_t gaintab[] = {
 0x35fa26
 };
 
+#define HDCD_PROCESS_STEREO_DEFAULT 1
+#define HDCD_MAX_CHANNELS 2
+
+/** convert to float from 4-bit (3.1) fixed-point
+ *  the always-negative value is stored positive, so make it negative */
+#define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
+
+/** apply gain, 11-bit (3.8) fixed point,
+ *  always negative but stored positive. */
+#define APPLY_GAIN(s,g) do{int64_t s64 = s; s64 *= gaintab[g]; s = 
(int32_t)(s64 >> 23); }while(0);
+
+/** tone generator: sample_number, frequency, sample_rate, amplitude */
+#define TONEGEN16(sn, f, sr, a) (int16_t)(sin((6.28318530718 * (sn) * (f)) 
/(sr)) * (a) * 0x7fff)
+
 typedef struct {
 uint64_t window;
 unsigned char readahead;
@@ -856,12 +870,14 @@ typedef struct {
 /** occurences of code detect timer expiring without detecting
  *  a code. -1 for timer never set. */
 int count_sustain_expired;
+
+int _ana_snb;   /**< used in the analyze mode tone generator */
 } hdcd_state_t;
 
 typedef enum {
-HDCD_PE_NEVER= 0,
-HDCD_PE_INTERMITTENT = 1,
-HDCD_PE_PERMANENT= 2,
+HDCD_PE_NEVER= 0, /**< All valid packets have PE set to off */
+HDCD_PE_INTERMITTENT = 1, /**< Some valid packets have PE set to on */
+HDCD_PE_PERMANENT= 2, /**< All valid packets have PE set to on  */
 } hdcd_pe_t;
 
 static const char * const pe_str[] = {
@@ -870,25 +886,51 @@ static const char * const pe_str[] = {
 "enabled permanently"
 };
 
-#define HDCD_PROCESS_STEREO_DEFAULT 1
-#define HDCD_MAX_CHANNELS 2
+typedef enum {
+HDCD_NONE= 0,  /**< HDCD packets do not (yet) appear  */
+HDCD_NO_EFFECT   = 1,  /**< HDCD packets appear, but all control codes 
are NOP */
+HDCD_EFFECTUAL   = 2,  /**< HDCD packets appear, and change the output 
in some way */
+} hdcd_detection_t;
 
-/** convert to float from 4-bit (3.1) fixed-point
- *  the always-negative value is stored positive, so make it negative */
-#define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
+typedef enum {
+HDCD_PVER_NONE   = 0, /**< No packets (yet) discovered */
+HDCD_PVER_A  = 1, /**< Packets of type A (8-bit control) 
discovered */
+HDCD_PVER_B  = 2, /**< Packets of type B (8-bit control, 8-bit 
XOR) discovered */
+HDCD_PVER_MIX= 3, /**< Packets of type A and B discovered, most 
likely an encoding error */
+} hdcd_pf_t;
+
+static const char * const pf_str[] = {
+"?", "A", "B", "A+B"
+};
+
+typedef struct {
+hdcd_detection_t hdcd_detected;
+hdcd_pf_t packet_type;
+int total_packets; /**< valid packets */
+int errors;/**< detectable errors */
+hdcd_pe_t peak_extend;
+int uses_transient_filter;
+float max_gain_adjustment; /**< in dB, expected in the range -7.5 to 0.0 */
+int cdt_expirations;   /**< -1 for never set, 0 for set but never 
expired */
 
-#define HDCD_ANA_OFF 0
+int _active_count; /**< used internally */
+} hdcd_detection_data_t;
+
+typedef enum {
+HDCD_ANA_OFF= 0,
+HDCD_ANA_LLE= 1,
+HDCD_ANA_PE = 2,
+HDCD_ANA_CDT= 3,
+HDCD_ANA_TGM= 4,
+HDCD_ANA_TOP= 5, /**< used in max value of AVOption */
+} hdcd_ana_mode_t;
+
+/** analyze mode descriptions: macro for AVOption definitions, array of const 
char for mapping mode to string */
 #define HDCD_ANA_OFF_DESC "disabled"
-#define HDCD_ANA_LLE 1
 #define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
-#define HDCD_ANA_PE  2
 #define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
-#define HDCD_ANA_CDT 3
 #define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
-#define HDCD_ANA_TGM 4
 #define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
-#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
-
 static const char * const ana_mode_str[] = {
 HDCD_ANA_OFF_DESC,
 HDCD_ANA_LLE_DESC,
@@ -917,7 +959,6 @@ 

Re: [FFmpeg-devel] [PATCH 2/3] af_hdcd: check return value of av_frame_copy_props()

2016-08-24 Thread Burt P.
applied

--
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/3] fate: add test for af_hdcd analyze mode

2016-08-24 Thread Burt P.
applied

--
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 0/3] libhdcd and things

2016-08-23 Thread Burt P.
On Tue, Aug 23, 2016 at 3:04 AM, Paul B Mahol  wrote:
> So you basically saying that foo* something will not use this lib, but
> lavfi will?
>
> What is point of lib than?

To use it in things other than ffmpeg. I personally use deadbeef and
quodlibet as music players, I would like to get support into those. I
have already created a plugin for deadbeef using the library, but
quodlibet uses gstreamer, and that is a bit intimidating, I don't know
that I'll get there.
Other people would also like to have HDCD decoding, and having this
library, perhaps, provides an easy way to get it into whatever player
they like.

Foobar2000 is a Windows only audio player, and the component foo_hdcd
is a plugin that adds HDCD decoding, and that code is what the filter
in ffmpeg is based on, but some of the work in ffmpeg has now gone
back into foo_hdcd, but not by using the shared library.

My objective is to get HDCD decoding in as much software as would like
to have it, but still have it all easy to maintain. Is that not a good
reason for a library?

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 0/3] libhdcd and things

2016-08-22 Thread Burt P.
Hi.

On Mon, Aug 22, 2016 at 7:52 PM, James Almer  wrote:
> A couple comments about the library.
>
> -The name hdcd_decode2 is still used in some places after your rename
> commit, like the installed header and main c file.
That is intentional. I want to keep the code there compatible with
foo_hdcd, with my additions all optional. foo_hdcd just drops
hdcd_decode2.{c,h} in, it doesn't use the shared library.
I've added a line to README.md that specifies the include line to use.

> -Does every struct currently defined in the installed header need to be
> there? Most if not all of the stuff in both hdcd_state_* structs kinda
> look like it could be internal, much like it currently is in af_hdcd.c
There could possibly be a simpler api that exposes less, but again,
foo_hdcd looks into those structures directly, I want to remain
compatible there. If you look at README.md, you should see that the
api is very simple to use as it is, even with the large exposure in
the header. The logging callback, detection, analyze mode, are all
optional features. The library does build as a windows dll, but I
don't know that the maintainer of foo_hdcd will be interested in that.

> You can play around with the API until you tag a first release.
I will do that soon.

> -Make the flags field int and update the relevant function signatures.
> You may not intend to add new flags now, but you may in the future, and
> uint8_t is too small for that.
Perhaps, ok.

> -Make sure it builds a shared library and symbols are visible.
It does build and work as a shared library as I far as I have tested
it, which is everything I can think of. Is there something specific
that is not visible or working?

> -Some doxy for the public functions would be nice.
I will add some code comments for that.

Thanks for your comments, any more are welcome.

--
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/3] fate: add test for af_hdcd analyze mode

2016-08-22 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 tests/fate/filter-audio.mak | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index d1d9d59..2066fa9 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -238,6 +238,12 @@ fate-filter-hdcd: CMD = md5 -i $(SRC) -af hdcd -f s24le
 fate-filter-hdcd: CMP = oneline
 fate-filter-hdcd: REF = 5db465a58d2fd0d06ca944b883b33476
 
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-analyze
+fate-filter-hdcd-analyze: SRC = $(TARGET_SAMPLES)/filter/hdcd.flac
+fate-filter-hdcd-analyze: CMD = md5 -i $(SRC) -af hdcd=analyze_mode=pe -f s24le
+fate-filter-hdcd-analyze: CMP = oneline
+fate-filter-hdcd-analyze: REF = 81a4f00f85a585bc0198e9a0670a8cde
+
 FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-false-positive
 fate-filter-hdcd-false-positive: SRC = 
$(TARGET_SAMPLES)/filter/hdcd-false-positive.flac
 fate-filter-hdcd-false-positive: CMD = md5 -i $(SRC) -af hdcd -f s24le
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/3] af_hdcd: for easier maintenance alongside libhdcd

2016-08-22 Thread Burt P
Mostly just re-arranges some code to make it easier to update this
filter and libhdcd together. filter_frame() is much simpler as a
result.

* use the HDCD detection data structure and functions from libhdcd
* moved detection code out of filter_frame()
* moved analyze_mode preparation out of filter_frame() into
  hdcd_analyze_prepare(), from libhdcd
* moved some macro definitions to the top so they are all together

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 275 --
 1 file changed, 175 insertions(+), 100 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 2324dc3..62071a6 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -823,6 +823,20 @@ static const int32_t gaintab[] = {
 0x35fa26
 };
 
+#define HDCD_PROCESS_STEREO_DEFAULT 1
+#define HDCD_MAX_CHANNELS 2
+
+/** convert to float from 4-bit (3.1) fixed-point
+ *  the always-negative value is stored positive, so make it negative */
+#define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
+
+/** apply gain, 11-bit (3.8) fixed point,
+ *  always negative but stored positive. */
+#define APPLY_GAIN(s,g) do{int64_t s64 = s; s64 *= gaintab[g]; s = 
(int32_t)(s64 >> 23); }while(0);
+
+/** tone generator: sample_number, frequency, sample_rate, amplitude */
+#define TONEGEN16(sn, f, sr, a) (int16_t)(sin((6.28318530718 * (sn) * (f)) 
/(sr)) * (a) * 0x7fff)
+
 typedef struct {
 uint64_t window;
 unsigned char readahead;
@@ -856,12 +870,14 @@ typedef struct {
 /** occurences of code detect timer expiring without detecting
  *  a code. -1 for timer never set. */
 int count_sustain_expired;
+
+int _ana_snb;   /**< used in the analyze mode tone generator */
 } hdcd_state_t;
 
 typedef enum {
-HDCD_PE_NEVER= 0,
-HDCD_PE_INTERMITTENT = 1,
-HDCD_PE_PERMANENT= 2,
+HDCD_PE_NEVER= 0, /**< All valid packets have PE set to off */
+HDCD_PE_INTERMITTENT = 1, /**< Some valid packets have PE set to on */
+HDCD_PE_PERMANENT= 2, /**< All valid packets have PE set to on  */
 } hdcd_pe_t;
 
 static const char * const pe_str[] = {
@@ -870,25 +886,51 @@ static const char * const pe_str[] = {
 "enabled permanently"
 };
 
-#define HDCD_PROCESS_STEREO_DEFAULT 1
-#define HDCD_MAX_CHANNELS 2
+typedef enum {
+HDCD_NONE= 0,  /**< HDCD packets do not (yet) appear  */
+HDCD_NO_EFFECT   = 1,  /**< HDCD packets appear, but all control codes 
are NOP */
+HDCD_EFFECTUAL   = 2,  /**< HDCD packets appear, and change the output 
in some way */
+} hdcd_detection_t;
 
-/** convert to float from 4-bit (3.1) fixed-point
- *  the always-negative value is stored positive, so make it negative */
-#define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
+typedef enum {
+HDCD_PVER_NONE   = 0, /**< No packets (yet) discovered */
+HDCD_PVER_A  = 1, /**< Packets of type A (8-bit control) 
discovered */
+HDCD_PVER_B  = 2, /**< Packets of type B (8-bit control, 8-bit 
XOR) discovered */
+HDCD_PVER_MIX= 3, /**< Packets of type A and B discovered, most 
likely an encoding error */
+} hdcd_pf_t;
+
+static const char * const pf_str[] = {
+"?", "A", "B", "A+B"
+};
+
+typedef struct {
+hdcd_detection_t hdcd_detected;
+hdcd_pf_t packet_type;
+int total_packets; /**< valid packets */
+int errors;/**< detectable errors */
+hdcd_pe_t peak_extend;
+int uses_transient_filter;
+float max_gain_adjustment; /**< in dB, expected in the range -7.5 to 0.0 */
+int cdt_expirations;   /**< -1 for never set, 0 for set but never 
expired */
 
-#define HDCD_ANA_OFF 0
+int _active_count; /**< used internally */
+} hdcd_detection_data_t;
+
+typedef enum {
+HDCD_ANA_OFF= 0,
+HDCD_ANA_LLE= 1,
+HDCD_ANA_PE = 2,
+HDCD_ANA_CDT= 3,
+HDCD_ANA_TGM= 4,
+HDCD_ANA_TOP= 5, /**< used in max value of AVOption */
+} hdcd_ana_mode_t;
+
+/** analyze mode descriptions: macro for AVOption definitions, array of const 
char for mapping mode to string */
 #define HDCD_ANA_OFF_DESC "disabled"
-#define HDCD_ANA_LLE 1
 #define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
-#define HDCD_ANA_PE  2
 #define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
-#define HDCD_ANA_CDT 3
 #define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
-#define HDCD_ANA_TGM 4
 #define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
-#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
-
 static const char * const ana_mode_str[] = {
 HDCD_ANA_OFF_DESC,
 HDCD_ANA_LLE_DESC,
@@ -917,7 +959,6 @@ 

[FFmpeg-devel] [PATCH 2/3] af_hdcd: check return value of av_frame_copy_props()

2016-08-22 Thread Burt P
Anton Khirnov:
"[av_frame_copy_props()] potentially contains memory allocation,
so the return value needs to be checked."

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 1bcd279..2324dc3 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1530,14 +1530,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 AVFrame *out;
 const int16_t *in_data;
 int32_t *out_data;
-int n, c;
+int n, c, result;
 
 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
 av_frame_free();
 return AVERROR(ENOMEM);
 }
-av_frame_copy_props(out, in);
+result = av_frame_copy_props(out, in);
+if (result) {
+av_frame_free();
+return result;
+}
 out->format = outlink->format;
 
 in_data  = (int16_t*)in->data[0];
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 0/3] libhdcd and things

2016-08-22 Thread Burt P
I have created a stand-alone library of the HDCD decoder from af_hdcd,
and called it libhdcd. [ https://github.com/bp0/libhdcd ]
I hope to use it in patches/plugins to some media players, and still
be able to easily maintain them both together. 

There is some concern that I wanted to remove the native code from the 
filter and use a wrapper of libhdcd, and I did think about that, but  
after comments on #ffmpeg-devel and in e-mail, I am convinced that is
wrong. I submitted a wrapper version to libav, however, as it was their
suggestion to do it that way to begin with.

The series also includes a couple small patches, self-described.

Thanks for comments.
--
Burt

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv5] af_hdcd: Extract generic HDCD decoder, wrap for ffmpeg

2016-08-19 Thread Burt P.
I've reconsidered and I think this change may not be a good idea at this time.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] af_volumedetect: Work with sample formats other than s16/s16p

2016-08-13 Thread Burt P.
On Sat, Aug 13, 2016 at 4:23 AM, Paul B Mahol  wrote:
>
> Also, swresample already does what converting code do, but faster.

Doing the conversion in the filter itself instead of using the
auto-inserted conversion filter is that the original data is left
completely untouched.
Using astats, the sample format is converted to DBL for the astats
filter and everything after.
I can't risk anything affecting the LSB of the input or the HDCD code
may be disrupted.


-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv2] avfiltergraph.c: restore disabling of auto conversions

2016-08-10 Thread Burt P.
applied

On Wed, Aug 10, 2016 at 4:09 AM, Burt P <pbu...@gmail.com> wrote:
> Restore a check added in 440af105f2306d3c7b3b3f4d7530bab910d49cb9
> but lost sometime after. avfilter_graph_set_auto_convert() will
> have an effect once again.
>
> Signed-off-by: Burt P <pbu...@gmail.com>
> ---
>  libavfilter/avfiltergraph.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index 4275113..3af698d 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -507,6 +507,14 @@ static int query_formats(AVFilterGraph *graph, AVClass 
> *log_ctx)
>  char scale_args[256];
>  char inst_name[30];
>
> +if (graph->disable_auto_convert) {
> +av_log(log_ctx, AV_LOG_ERROR,
> +   "The filters '%s' and '%s' do not have a common 
> format "
> +   "and automatic conversion is disabled.\n",
> +   link->src->name, link->dst->name);
> +return AVERROR(EINVAL);
> +}
> +
>  /* couldn't merge format lists. auto-insert conversion 
> filter */
>  switch (link->type) {
>  case AVMEDIA_TYPE_VIDEO:
> --
> 2.7.4
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] avfilter_graph_set_auto_convert() appears to do nothing

2016-08-10 Thread Burt P.
Now reading to the end of the original message by Nicolas George,
which I should have done before, I can see that it is already known to
be lost.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] avfiltergraph.c: restore disabling of auto conversions

2016-08-10 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/avfiltergraph.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 4275113..1685b76 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -507,6 +507,14 @@ static int query_formats(AVFilterGraph *graph, AVClass 
*log_ctx)
 char scale_args[256];
 char inst_name[30];
 
+if (graph->disable_auto_convert) {
+av_log(NULL, AV_LOG_ERROR,
+   "The filters '%s' and '%s' do not have a common 
format "
+   "and automatic conversion is disabled.\n",
+   link->src->name, link->dst->name);
+return AVERROR(EINVAL);
+}
+
 /* couldn't merge format lists. auto-insert conversion filter 
*/
 switch (link->type) {
 case AVMEDIA_TYPE_VIDEO:
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv2] avfiltergraph.c: restore disabling of auto conversions

2016-08-10 Thread Burt P
Restore a check added in 440af105f2306d3c7b3b3f4d7530bab910d49cb9
but lost sometime after. avfilter_graph_set_auto_convert() will
have an effect once again.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/avfiltergraph.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 4275113..3af698d 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -507,6 +507,14 @@ static int query_formats(AVFilterGraph *graph, AVClass 
*log_ctx)
 char scale_args[256];
 char inst_name[30];
 
+if (graph->disable_auto_convert) {
+av_log(log_ctx, AV_LOG_ERROR,
+   "The filters '%s' and '%s' do not have a common 
format "
+   "and automatic conversion is disabled.\n",
+   link->src->name, link->dst->name);
+return AVERROR(EINVAL);
+}
+
 /* couldn't merge format lists. auto-insert conversion filter 
*/
 switch (link->type) {
 case AVMEDIA_TYPE_VIDEO:
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] avfilter_graph_set_auto_convert() appears to do nothing

2016-08-10 Thread Burt P.
As suggested by Nicolas George, I've recently tried
avfilter_graph_set_auto_convert(ctx->graph, AVFILTER_AUTO_CONVERT_NONE)
in a filter init() function, but it did not prevent auto-inserted
resampling filters from appearing.

I looked around a bit and could not find a place where the member of
AVFilterGraph that is set by the function is actually used in master.
[1]

The function, and a check of the flag during the conversion filter
auto-insertion process, was added in
440af105f2306d3c7b3b3f4d7530bab910d49cb9 [2]
but the check seems to have been removed later on, leaving only the
ineffectual function.

[1] 
https://github.com/FFmpeg/FFmpeg/search?utf8=%E2%9C%93=disable_auto_convert
[2] 
https://github.com/FFmpeg/FFmpeg/commit/440af105f2306d3c7b3b3f4d7530bab910d49cb9

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P

2016-08-08 Thread Burt P.
applied, as dbd7a84c814161926e5f298eae1f5ea17082f814, with an
additional check that AVFilterLink->type is AVMEDIA_TYPE_AUDIO before
calling av_get_sample_fmt_name() on AVFilterLink->format. Thanks for
pointing that out.

I will look into disabling auto-conversions when the filter is used
and removing the invasive scan.


On Mon, Aug 8, 2016 at 5:16 AM, Nicolas George <geo...@nsup.org> wrote:
> Le primidi 21 thermidor, an CCXXIV, Burt P. a écrit :
>> Are you now talking about plans of the future or this specific case?
>
> Both.
>
>> As it is, automatic conversion is very helpful, for example from
>> WavePack, which uses s16p.
>
> Apparently, not all of them are to your liking. FFmpeg can not guess which
> ones. You could try to teach it, but it may prove tricky. The best solution
> is to let the user choose, and that is exactly what disabling the automatic
> conversion does.
>
> Note that it does not disable conversions, only automatic ones. It also does
> not disable format negotiation. The only thing that changes is that the user
> has to choose where the conversion happens.
>
>> This filter is only looking at the AVFilterLinks between filters, not
>> at the filters themselves.
>
> And with lavfi's design, this is not allowed. As is, the filter is scanning
> links that it does not even know are audio, let alone are in any way
> connected to it.
>
>> This scan and warn behavior was added to address a real issue.
>
> That is more or less the Transportation Security Administration's motto, and
> we all know what a catastrophe that is. Good intentions are not enough to
> make a solution correct, and this solution is not correct at all.
>
>> Consider these example cases:
>
> None of them involve anything remotely complicated.
>
> Regards,
>
> --
>   Nicolas George
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv5] af_hdcd: Add analyze mode

2016-08-08 Thread Burt P.
applied

On Sun, Aug 7, 2016 at 2:50 AM, Burt P <pbu...@gmail.com> wrote:
> A new mode, selected by filter option, to aid in analysis of HDCD
> encoded audio. In this mode the audio is replaced by a solid tone and
> the amplitude is adjusted to signal some specified aspect of the process.
> The output file can be loaded in an audio editor alongside the original,
> where the user can see where different features or states are present.
>
> Signed-off-by: Burt P <pbu...@gmail.com>
> ---
>  doc/filters.texi  |  32 ++
>  libavfilter/af_hdcd.c | 163 
> +++---
>  2 files changed, 187 insertions(+), 8 deletions(-)


-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P

2016-08-07 Thread Burt P.
Are you now talking about plans of the future or this specific case?

As it is, automatic conversion is very helpful, for example from
WavePack, which uses s16p.
This filter is only looking at the AVFilterLinks between filters, not
at the filters themselves.
This scan and warn behavior was added to address a real issue.

Consider these example cases:
ffmpeg -i hdcd16.wv -af hdcd hdcd24.flac
* .wv uses s16p, auto-converted to s16, nice!
* hdcd is decoded without problem
* 24-bit flac is output, ok

ffmpeg -i hdcd16.wv -af hdcd hdcd24-expected.wav
* .wv uses s16p, auto-converted to s16, nice!
* hdcd is decoded without problem
* s32 is converted to s16 for wav by default, but user expects it to
be more than 16-bit!
--- a warning is issued about the truncation

ffmpeg -i hdcd16.flac -af hdcd hdcdout.m4a
* .flac has s16 samples, passed without problem
* hdcd is decoded without problem
* native aac encodes the full range, ok!

ffmpeg -i hdcd16.flac -af hdcd -c:a libfdk_aac hdcd-dec.m4a
* .flac has s16 samples, passed without problem
* hdcd is decoded without problem
* autoconverted to s16 for libfdk-aac, but the user doesn't know that
the "best available aac encoder" only accepts s16 input!
--- a warning is issued about the truncation

ffmpeg -i anything_not_s16 -af hdcd hdcd24.flac
* input is anything that is not likely to have hdcd
* it is converted to s16 for the filter
--- a warning is issued about the format conversion

I think the automatic conversion from s16p, and into fltp when needed
is very good and I'd like to keep it, but I would also like to warn
when there might be a problem.
As I understand it though, you think auto-inserted filters should be
off, and the user will have to manually add conversions for
WavePack/s16 and the like before, and conversion to fltp, s24, etc.
after.


On Sun, Aug 7, 2016 at 5:23 PM, Nicolas George  wrote:
> Le primidi 21 thermidor, an CCXXIV, Carl Eugen Hoyos a écrit :
>> Wouldn't that disable any automatic conversion behind (after) the
>> hdcd filter? If that is correct, I would not consider it a better solution.
>
> The filter already checks for conversions after itself too.
>
> Conversion can still happen, but only at explicit points.
>
> Regards,
>
> --
>   Nicolas George
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P

2016-08-07 Thread Burt P.
On Sun, Aug 7, 2016 at 12:20 PM, Nicolas George  wrote:
> Sorry if it has been addressed before, but what are these tests? Why is this
> filter invading other filters' privacy?
The HDCD codes are stored in the LSB of consecutive samples, and
anything that would change a sample could cause problems. So it looks
through the AVFilterLink chain and warns if any resampling or
truncation is happening that might destroy the HDCD code before or
undo the filter's work after.

-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P

2016-08-07 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index e4e37e2..ebfe0f1 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1714,7 +1714,9 @@ static int config_input(AVFilterLink *inlink) {
 AVFilterLink *lk = inlink;
 while(lk != NULL) {
 AVFilterContext *nextf = lk->src;
-if (lk->format != AV_SAMPLE_FMT_S16 || lk->sample_rate != 44100) {
+int sfok = (lk->format == AV_SAMPLE_FMT_S16 ||
+lk->format == AV_SAMPLE_FMT_S16P);
+if ( !sfok || lk->sample_rate != 44100) {
 av_log(ctx, AV_LOG_WARNING, "An input format is %s@%dHz at %s. It 
will truncated/resampled to s16@44100Hz.\n",
 av_get_sample_fmt_name(lk->format), lk->sample_rate,
 (nextf->name) ? nextf->name : ""
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P

2016-08-07 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index e4e37e2..36da409 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1714,7 +1714,9 @@ static int config_input(AVFilterLink *inlink) {
 AVFilterLink *lk = inlink;
 while(lk != NULL) {
 AVFilterContext *nextf = lk->src;
-if (lk->format != AV_SAMPLE_FMT_S16 || lk->sample_rate != 44100) {
+int sfok = (lk->format == AV_SAMPLE_FMT_S16
+ || lk->format == AV_SAMPLE_FMT_S16P);
+if ( !sfok || lk->sample_rate != 44100) {
 av_log(ctx, AV_LOG_WARNING, "An input format is %s@%dHz at %s. It 
will truncated/resampled to s16@44100Hz.\n",
 av_get_sample_fmt_name(lk->format), lk->sample_rate,
 (nextf->name) ? nextf->name : ""
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv5] af_hdcd: Add analyze mode

2016-08-07 Thread Burt P
A new mode, selected by filter option, to aid in analysis of HDCD
encoded audio. In this mode the audio is replaced by a solid tone and
the amplitude is adjusted to signal some specified aspect of the process.
The output file can be loaded in an audio editor alongside the original,
where the user can see where different features or states are present.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 doc/filters.texi  |  32 ++
 libavfilter/af_hdcd.c | 163 +++---
 2 files changed, 187 insertions(+), 8 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 7e042e4..0d0684f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -8454,6 +8454,38 @@ ffmpeg -i HDCD16.wav -af hdcd OUT16.wav
 ffmpeg -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav
 @end example
 
+The filter accepts the following options:
+
+@table @option
+@item process_stereo
+Process the stereo channels together. If target_gain does not match between
+channels, consider it invalid and use the last valid target_gain.
+
+@item force_pe
+Always extend peaks above -3dBFS even if PE isn't signaled.
+
+@item analyze_mode
+Replace audio with a solid tone and adjust the amplitude to signal some
+specific aspect of the decoding process. The output file can be loaded in
+an audio editor alongside the original to aid analysis.
+
+@code{analyze_mode=pe:force_pe=1} can be used to see all samples above the PE 
level.
+
+Modes are:
+@table @samp
+@item 0, off
+Disabled
+@item 1, lle
+Gain adjustment level at each sample
+@item 2, pe
+Samples where peak extend occurs
+@item 3, cdt
+Samples where the code detect timer is active
+@item 4, tgm
+Samples where the target gain does not match between channels
+@end table
+@end table
+
 @section hflip
 
 Flip the input video horizontally.
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 610dd9e..e4e37e2 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -870,6 +870,26 @@ static const char * const pe_str[] = {
  * the always-negative value is stored positive, so make it negative */
 #define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
 
+#define HDCD_ANA_OFF 0
+#define HDCD_ANA_OFF_DESC "disabled"
+#define HDCD_ANA_LLE 1
+#define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
+#define HDCD_ANA_PE  2
+#define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
+#define HDCD_ANA_CDT 3
+#define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
+#define HDCD_ANA_TGM 4
+#define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
+#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
+
+static const char * const ana_mode_str[] = {
+HDCD_ANA_OFF_DESC,
+HDCD_ANA_LLE_DESC,
+HDCD_ANA_PE_DESC,
+HDCD_ANA_CDT_DESC,
+HDCD_ANA_TGM_DESC,
+};
+
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[HDCD_MAX_CHANNELS];
@@ -885,6 +905,12 @@ typedef struct HDCDContext {
  * default is off */
 int force_pe;
 
+/* analyze mode replaces the audio with a solid tone and adjusts
+ * the amplitude to signal some specific aspect of the decoding
+ * process. See docs or HDCD_ANA_* defines. */
+int analyze_mode;
+int ana_snb;/* used in tone generation */
+
 /* config_input() and config_output() scan links for any resampling
  * or format changes. If found, warnings are issued and bad_config
  * is set. */
@@ -909,6 +935,13 @@ static const AVOption hdcd_options[] = {
 OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
+{ "analyze_mode",  "Replace audio with solid tone and signal some 
processing aspect in the amplitude.",
+OFFSET(analyze_mode), AV_OPT_TYPE_INT, { .i64=HDCD_ANA_OFF }, 0, 
HDCD_ANA_TOP-1, A, "analyze_mode"},
+{ "off", HDCD_ANA_OFF_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_OFF}, 
0, 0, A, "analyze_mode" },
+{ "lle", HDCD_ANA_LLE_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_LLE}, 
0, 0, A, "analyze_mode" },
+{ "pe",  HDCD_ANA_PE_DESC,  0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_PE},  
0, 0, A, "analyze_mode" },
+{ "cdt", HDCD_ANA_CDT_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_CDT}, 
0, 0, A, "analyze_mode" },
+{ "tgm", HDCD_ANA_TGM_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_TGM}, 
0, 0, A, "analyze_mode" },
 {NULL}
 };
 
@@ -1209,6 +1242,77 @@ static int hdcd_scan_stereo(HDCDContext *ctx, const 
int32_t *samples, int max)
 return result;
 }
 
+/* encode a value in the given sample by adjust

[FFmpeg-devel] [PATCHv4] af_hdcd: Add analyze mode (v4)

2016-08-07 Thread Burt P
A new mode, selected by filter option, to aid in analysis of HDCD
encoded audio. In this mode the audio is replaced by a solid tone and
the amplitude is adjusted to signal some specified aspect of the process.
The output file can be loaded in an audio editor alongside the original,
where the user can see where different features or states are present.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 doc/filters.texi  |  32 ++
 libavfilter/af_hdcd.c | 163 +++---
 2 files changed, 187 insertions(+), 8 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 7e042e4..0d0684f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -8454,6 +8454,38 @@ ffmpeg -i HDCD16.wav -af hdcd OUT16.wav
 ffmpeg -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav
 @end example
 
+The filter accepts the following options:
+
+@table @option
+@item process_stereo
+Process the stereo channels together. If target_gain does not match between
+channels, consider it invalid and use the last valid target_gain.
+
+@item force_pe
+Always extend peaks above -3dBFS even if PE isn't signaled.
+
+@item analyze_mode
+Replace audio with a solid tone and adjust the amplitude to signal some
+specific aspect of the decoding process. The output file can be loaded in
+an audio editor alongside the original to aid analysis.
+
+@code{analyze_mode=pe:force_pe=1} can be used to see all samples above the PE 
level.
+
+Modes are:
+@table @samp
+@item 0, off
+Disabled
+@item 1, lle
+Gain adjustment level at each sample
+@item 2, pe
+Samples where peak extend occurs
+@item 3, cdt
+Samples where the code detect timer is active
+@item 4, tgm
+Samples where the target gain does not match between channels
+@end table
+@end table
+
 @section hflip
 
 Flip the input video horizontally.
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 610dd9e..5532528 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -870,6 +870,26 @@ static const char * const pe_str[] = {
  * the always-negative value is stored positive, so make it negative */
 #define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
 
+#define HDCD_ANA_OFF 0
+#define HDCD_ANA_OFF_DESC "disabled"
+#define HDCD_ANA_LLE 1
+#define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
+#define HDCD_ANA_PE  2
+#define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
+#define HDCD_ANA_CDT 3
+#define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
+#define HDCD_ANA_TGM 4
+#define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
+#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
+
+static const char * const ana_mode_str[] = {
+HDCD_ANA_OFF_DESC,
+HDCD_ANA_LLE_DESC,
+HDCD_ANA_PE_DESC,
+HDCD_ANA_CDT_DESC,
+HDCD_ANA_TGM_DESC,
+};
+
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[HDCD_MAX_CHANNELS];
@@ -885,6 +905,12 @@ typedef struct HDCDContext {
  * default is off */
 int force_pe;
 
+/* analyze mode replaces the audio with a solid tone and adjusts
+ * the amplitude to signal some specific aspect of the decoding
+ * process. See docs or HDCD_ANA_* defines. */
+int analyze_mode;
+int ana_snb;/* used in tone generation */
+
 /* config_input() and config_output() scan links for any resampling
  * or format changes. If found, warnings are issued and bad_config
  * is set. */
@@ -909,6 +935,13 @@ static const AVOption hdcd_options[] = {
 OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
+{ "analyze_mode",  "Replace audio with solid tone and signal some 
processing aspect in the amplitude.",
+OFFSET(analyze_mode), AV_OPT_TYPE_INT, { .i64=HDCD_ANA_OFF }, 0, 
HDCD_ANA_TOP-1, A, "analyze_mode"},
+{ "off", HDCD_ANA_OFF_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_OFF}, 
0, 0, A, "analyze_mode" },
+{ "lle", HDCD_ANA_LLE_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_LLE}, 
0, 0, A, "analyze_mode" },
+{ "pe",  HDCD_ANA_PE_DESC,  0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_PE},  
0, 0, A, "analyze_mode" },
+{ "cdt", HDCD_ANA_CDT_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_CDT}, 
0, 0, A, "analyze_mode" },
+{ "tgm", HDCD_ANA_TGM_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_TGM}, 
0, 0, A, "analyze_mode" },
 {NULL}
 };
 
@@ -1209,6 +1242,77 @@ static int hdcd_scan_stereo(HDCDContext *ctx, const 
int32_t *samples, int max)
 return result;
 }
 
+/* encode a value in the given sample by adjust

Re: [FFmpeg-devel] [PATCH 2/2] aacenc: unmark the fast coder as experimental

2016-08-07 Thread Burt P.
"The ANMR coder requires -strict -2 and some may be removed in the future"
should have "some" removed.

On Sat, Aug 6, 2016 at 6:51 PM, Rostislav Pehlivanov
 wrote:
> This version has had much testing so there's little point in keeping it
> maked as experimental.
>
> Signed-off-by: Rostislav Pehlivanov 
> ---
>  libavcodec/aacenc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
> index 2653cef..1d80a67 100644
> --- a/libavcodec/aacenc.c
> +++ b/libavcodec/aacenc.c
> @@ -999,9 +999,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
>
>  /* Coder limitations */
>  s->coder = _aac_coders[s->options.coder];
> -if (s->options.coder != AAC_CODER_TWOLOOP) {
> +if (s->options.coder == AAC_CODER_ANMR) {
>  ERROR_IF(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL,
> - "Coders other than twoloop require -strict -2 and some may 
> be removed in the future\n");
> + "The ANMR coder requires -strict -2 and some may be removed 
> in the future\n");
>  s->options.intensity_stereo = 0;
>  s->options.pns = 0;
>  }
> --
> 2.8.1.369.geae769a
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/2] af_hdcd: convert AVOptions from INT to BOOL

2016-08-06 Thread Burt P.
applied

thx :)



On Fri, Aug 5, 2016 at 4:54 PM, Burt P <pbu...@gmail.com> wrote:
> As suggested by Timothy Gu.
>
> Signed-off-by: Burt P <pbu...@gmail.com>
> ---
>  libavfilter/af_hdcd.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
> index ef3c369..610dd9e 100644
> --- a/libavfilter/af_hdcd.c
> +++ b/libavfilter/af_hdcd.c
> @@ -906,9 +906,9 @@ typedef struct HDCDContext {
>  #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
>  static const AVOption hdcd_options[] = {
>  { "process_stereo", "Process stereo channels together. Only apply 
> target_gain when both channels match.",
> -OFFSET(process_stereo), AV_OPT_TYPE_INT, { .i64 = 
> HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
> +OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
> HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
>  { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
> signaled.",
> -OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, A },
> +OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
>  {NULL}
>  };
>
> --
> 2.7.4
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv3] af_hdcd: Add analyze mode (v3)

2016-08-06 Thread Burt P
A new mode, selected by filter option, to aid in analysis of HDCD
encoded audio. In this mode the audio is replaced by a solid tone and
the amplitude is adjusted to signal some specified aspect of the process.
The output file can be loaded in an audio editor alongside the original,
where the user can see where different features or states are present.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 doc/filters.texi  |  32 ++
 libavfilter/af_hdcd.c | 164 +++---
 2 files changed, 188 insertions(+), 8 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 7e042e4..0d0684f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -8454,6 +8454,38 @@ ffmpeg -i HDCD16.wav -af hdcd OUT16.wav
 ffmpeg -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav
 @end example
 
+The filter accepts the following options:
+
+@table @option
+@item process_stereo
+Process the stereo channels together. If target_gain does not match between
+channels, consider it invalid and use the last valid target_gain.
+
+@item force_pe
+Always extend peaks above -3dBFS even if PE isn't signaled.
+
+@item analyze_mode
+Replace audio with a solid tone and adjust the amplitude to signal some
+specific aspect of the decoding process. The output file can be loaded in
+an audio editor alongside the original to aid analysis.
+
+@code{analyze_mode=pe:force_pe=1} can be used to see all samples above the PE 
level.
+
+Modes are:
+@table @samp
+@item 0, off
+Disabled
+@item 1, lle
+Gain adjustment level at each sample
+@item 2, pe
+Samples where peak extend occurs
+@item 3, cdt
+Samples where the code detect timer is active
+@item 4, tgm
+Samples where the target gain does not match between channels
+@end table
+@end table
+
 @section hflip
 
 Flip the input video horizontally.
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 610dd9e..ada30f4 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -870,6 +870,27 @@ static const char * const pe_str[] = {
  * the always-negative value is stored positive, so make it negative */
 #define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
 
+#define HDCD_ANA_OFF 0
+#define HDCD_ANA_OFF_DESC "disabled"
+#define HDCD_ANA_LLE 1
+#define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
+#define HDCD_ANA_PE  2
+#define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
+#define HDCD_ANA_CDT 3
+#define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
+#define HDCD_ANA_TGM 4
+#define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
+#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
+typedef int hdcd_ana_mode_t; /* formerly enum, but that didn't work for 
AVOption initialization */
+
+static const char * const ana_mode_str[] = {
+HDCD_ANA_OFF_DESC,
+HDCD_ANA_LLE_DESC,
+HDCD_ANA_PE_DESC,
+HDCD_ANA_CDT_DESC,
+HDCD_ANA_TGM_DESC,
+};
+
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[HDCD_MAX_CHANNELS];
@@ -885,6 +906,12 @@ typedef struct HDCDContext {
  * default is off */
 int force_pe;
 
+/* analyze mode replaces the audio with a solid tone and adjusts
+ * the amplitude to signal some specific aspect of the decoding
+ * process. See docs or hdcd_ana_mode_t */
+hdcd_ana_mode_t analyze_mode;
+int ana_snb;/* used in tone generation */
+
 /* config_input() and config_output() scan links for any resampling
  * or format changes. If found, warnings are issued and bad_config
  * is set. */
@@ -909,6 +936,13 @@ static const AVOption hdcd_options[] = {
 OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
+{ "analyze_mode",  "Replace audio with solid tone and signal some 
processing aspect in the amplitude.",
+OFFSET(analyze_mode), AV_OPT_TYPE_INT, { .i64=HDCD_ANA_OFF }, 0, 
HDCD_ANA_TOP-1, A, "analyze_mode"},
+{ "off", HDCD_ANA_OFF_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_OFF}, 
0, 0, A, "analyze_mode" },
+{ "lle", HDCD_ANA_LLE_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_LLE}, 
0, 0, A, "analyze_mode" },
+{ "pe",  HDCD_ANA_PE_DESC,  0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_PE},  
0, 0, A, "analyze_mode" },
+{ "cdt", HDCD_ANA_CDT_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_CDT}, 
0, 0, A, "analyze_mode" },
+{ "tgm", HDCD_ANA_TGM_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_TGM}, 
0, 0, A, "analyze_mode" },
 {NULL}
 };
 
@@ -1209,6 +1243,77 @@ static int hdcd_scan_stereo(HDCDContext *

[FFmpeg-devel] [PATCHv2] af_hdcd: Add analyze mode

2016-08-05 Thread Burt P
A new mode, selected by filter option, to aid in analysis of HDCD
encoded audio. In this mode the audio is replaced by a solid tone and
the amplitude is adjusted to signal some specified aspect of the process.
The output file can be loaded in an audio editor alongside the original,
where the user can see where different features or states are present.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 doc/filters.texi  |  32 ++
 libavfilter/af_hdcd.c | 164 +++---
 2 files changed, 188 insertions(+), 8 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 7e042e4..0d0684f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -8454,6 +8454,38 @@ ffmpeg -i HDCD16.wav -af hdcd OUT16.wav
 ffmpeg -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav
 @end example
 
+The filter accepts the following options:
+
+@table @option
+@item process_stereo
+Process the stereo channels together. If target_gain does not match between
+channels, consider it invalid and use the last valid target_gain.
+
+@item force_pe
+Always extend peaks above -3dBFS even if PE isn't signaled.
+
+@item analyze_mode
+Replace audio with a solid tone and adjust the amplitude to signal some
+specific aspect of the decoding process. The output file can be loaded in
+an audio editor alongside the original to aid analysis.
+
+@code{analyze_mode=pe:force_pe=1} can be used to see all samples above the PE 
level.
+
+Modes are:
+@table @samp
+@item 0, off
+Disabled
+@item 1, lle
+Gain adjustment level at each sample
+@item 2, pe
+Samples where peak extend occurs
+@item 3, cdt
+Samples where the code detect timer is active
+@item 4, tgm
+Samples where the target gain does not match between channels
+@end table
+@end table
+
 @section hflip
 
 Flip the input video horizontally.
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 610dd9e..edf3138 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -870,6 +870,27 @@ static const char * const pe_str[] = {
  * the always-negative value is stored positive, so make it negative */
 #define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
 
+#define HDCD_ANA_OFF 0
+#define HDCD_ANA_OFF_DESC "disabled"
+#define HDCD_ANA_LLE 1
+#define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
+#define HDCD_ANA_PE  2
+#define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
+#define HDCD_ANA_CDT 3
+#define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
+#define HDCD_ANA_TGM 4
+#define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
+#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
+typedef int hdcd_ana_mode_t; /* formerly enum, but that didn't work for 
AVOption initialization */
+
+static const char * const ana_mode_str[] = {
+HDCD_ANA_OFF_DESC,
+HDCD_ANA_LLE_DESC,
+HDCD_ANA_PE_DESC,
+HDCD_ANA_CDT_DESC,
+HDCD_ANA_TGM_DESC,
+};
+
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[HDCD_MAX_CHANNELS];
@@ -885,6 +906,12 @@ typedef struct HDCDContext {
  * default is off */
 int force_pe;
 
+/* analyze mode replaces the audio with a solid tone and adjusts
+ * the amplitude to signal some specific aspect of the decoding
+ * process. See docs or hdcd_ana_mode_t */
+hdcd_ana_mode_t analyze_mode;
+int ana_snb;/* used in tone generation */
+
 /* config_input() and config_output() scan links for any resampling
  * or format changes. If found, warnings are issued and bad_config
  * is set. */
@@ -909,6 +936,13 @@ static const AVOption hdcd_options[] = {
 OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
+{ "analyze_mode",  "Replace audio with solid tone and signal some 
processing aspect in the amplitude.",
+OFFSET(analyze_mode), AV_OPT_TYPE_INT, { .i64=HDCD_ANA_OFF }, 0, 
HDCD_ANA_TOP-1, A, "analyze_mode"},
+{ "off", HDCD_ANA_OFF_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_OFF}, 
0, 0, A, "analyze_mode" },
+{ "lle", HDCD_ANA_LLE_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_LLE}, 
0, 0, A, "analyze_mode" },
+{ "pe",  HDCD_ANA_PE_DESC,  0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_PE},  
0, 0, A, "analyze_mode" },
+{ "cdt", HDCD_ANA_CDT_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_CDT}, 
0, 0, A, "analyze_mode" },
+{ "tgm", HDCD_ANA_TGM_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_TGM}, 
0, 0, A, "analyze_mode" },
 {NULL}
 };
 
@@ -1209,6 +1243,77 @@ static int hdcd_scan_stereo(HDCDContext *

[FFmpeg-devel] [PATCH 1/2] af_hdcd: convert AVOptions from INT to BOOL

2016-08-05 Thread Burt P
As suggested by Timothy Gu.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index ef3c369..610dd9e 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -906,9 +906,9 @@ typedef struct HDCDContext {
 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption hdcd_options[] = {
 { "process_stereo", "Process stereo channels together. Only apply 
target_gain when both channels match.",
-OFFSET(process_stereo), AV_OPT_TYPE_INT, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
+OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
-OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, A },
+OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
 {NULL}
 };
 
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/2] af_hdcd: Add analyze mode

2016-08-05 Thread Burt P
A new mode, selected by filter option, to aid in analysis of HDCD
encoded audio. In this mode the audio is replaced by a solid tone and
the amplitude is adjusted to signal some specified aspect of the process.
The output file can be loaded in an audio editor alongside the original,
where the user can see where different features or states are present.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 doc/filters.texi  |  32 ++
 libavfilter/af_hdcd.c | 164 +++---
 2 files changed, 188 insertions(+), 8 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 7e042e4..e8df2ee 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -8454,6 +8454,38 @@ ffmpeg -i HDCD16.wav -af hdcd OUT16.wav
 ffmpeg -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav
 @end example
 
+The filter accepts the following options:
+
+@table @option
+@item process_mode
+Process the stereo channels together. If target_gain does not match between
+channels, consider it invalid and use the last valid target_gain.
+
+@item force_pe
+Always extend peaks above -3dBFS even if PE isn't signaled.
+
+@item analyze_mode
+Replace audio with a solid tone and adjust the amplitude to signal some
+specific aspect of the decoding process. The output file can be loaded in
+an audio editor alongside the original to aid analysis.
+
+@code{analyze_mode=pe:force_pe=1} can be used to see all samples above the PE 
level.
+
+Modes are:
+@table @samp
+@item 0, off
+Disabled
+@item 1, lle
+Gain adjustment level at each sample
+@item 2, pe
+Samples where peak extend occurs
+@item 3, cdt
+Samples where the code detect timer is active
+@item 4, tgm
+Samples where the target gain does not match between channels
+@end table
+@end table
+
 @section hflip
 
 Flip the input video horizontally.
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 610dd9e..edf3138 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -870,6 +870,27 @@ static const char * const pe_str[] = {
  * the always-negative value is stored positive, so make it negative */
 #define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
 
+#define HDCD_ANA_OFF 0
+#define HDCD_ANA_OFF_DESC "disabled"
+#define HDCD_ANA_LLE 1
+#define HDCD_ANA_LLE_DESC "gain adjustment level at each sample"
+#define HDCD_ANA_PE  2
+#define HDCD_ANA_PE_DESC  "samples where peak extend occurs"
+#define HDCD_ANA_CDT 3
+#define HDCD_ANA_CDT_DESC "samples where the code detect timer is active"
+#define HDCD_ANA_TGM 4
+#define HDCD_ANA_TGM_DESC "samples where the target gain does not match 
between channels"
+#define HDCD_ANA_TOP 5 /* used in max value of AVOption */
+typedef int hdcd_ana_mode_t; /* formerly enum, but that didn't work for 
AVOption initialization */
+
+static const char * const ana_mode_str[] = {
+HDCD_ANA_OFF_DESC,
+HDCD_ANA_LLE_DESC,
+HDCD_ANA_PE_DESC,
+HDCD_ANA_CDT_DESC,
+HDCD_ANA_TGM_DESC,
+};
+
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[HDCD_MAX_CHANNELS];
@@ -885,6 +906,12 @@ typedef struct HDCDContext {
  * default is off */
 int force_pe;
 
+/* analyze mode replaces the audio with a solid tone and adjusts
+ * the amplitude to signal some specific aspect of the decoding
+ * process. See docs or hdcd_ana_mode_t */
+hdcd_ana_mode_t analyze_mode;
+int ana_snb;/* used in tone generation */
+
 /* config_input() and config_output() scan links for any resampling
  * or format changes. If found, warnings are issued and bad_config
  * is set. */
@@ -909,6 +936,13 @@ static const AVOption hdcd_options[] = {
 OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A },
+{ "analyze_mode",  "Replace audio with solid tone and signal some 
processing aspect in the amplitude.",
+OFFSET(analyze_mode), AV_OPT_TYPE_INT, { .i64=HDCD_ANA_OFF }, 0, 
HDCD_ANA_TOP-1, A, "analyze_mode"},
+{ "off", HDCD_ANA_OFF_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_OFF}, 
0, 0, A, "analyze_mode" },
+{ "lle", HDCD_ANA_LLE_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_LLE}, 
0, 0, A, "analyze_mode" },
+{ "pe",  HDCD_ANA_PE_DESC,  0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_PE},  
0, 0, A, "analyze_mode" },
+{ "cdt", HDCD_ANA_CDT_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_CDT}, 
0, 0, A, "analyze_mode" },
+{ "tgm", HDCD_ANA_TGM_DESC, 0, AV_OPT_TYPE_CONST, {.i64=HDCD_ANA_TGM}, 
0, 0, A, "analyze_mode" },
 {NULL}
 };
 
@@ -1209,6 +1243,77 @@ static int hdcd_scan_stereo(HDCDContext *

[FFmpeg-devel] [PATCH 0/2] Analyze mode

2016-08-05 Thread Burt P
1. Converts a couple AVOptions from INT to BOOL as suggested.
2. Adds a mode that is useful to analyze the HDCD encoding, and
find interesting samples to examine more closely.

Thanks for any comments.

--
Burt

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] FFmpeg 3.1.2

2016-08-05 Thread Burt P.
Can this small fix be applied to 3.1?

http://ffmpeg.org/pipermail/ffmpeg-devel/2016-July/196268.html
Although, if you can, please fix my typo in the subject, bing -> being. :/

On Thu, Aug 4, 2016 at 5:25 AM, Michael Niedermayer
 wrote:
> Hi all
>
> ill soon make FFmpeg 3.1.2
> that is if someone wants something backported, do it now!
>
> thx
>
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> The bravest are surely those who have the clearest vision
> of what is before them, glory and danger alike, and yet
> notwithstanding go out to meet it. -- Thucydides
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCHv2] af_hdcd: Process stereo channels together, fix #5727

2016-08-01 Thread Burt P
Issue #5727: gain adjustment should only be applied if matching
gain value from a valid packet in both channels. The existing functions process
each channel separately, so it was not possible.

* New versions of hdcd_process(), hdcd_scan(), hdcd_integrate() named
  hdcd_*_stereo() that process both channels together.
* target_gain applied will be the last matching target_gain.
* The old single channel functions remain as an option. They can be
  used by: -af hdcd=process_stereo=0.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 287 +++---
 1 file changed, 249 insertions(+), 38 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 0752c39..683c588 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -863,10 +863,22 @@ static const char * const pe_str[] = {
 "enabled permanently"
 };
 
+#define HDCD_PROCESS_STEREO_DEFAULT 1
+#define HDCD_MAX_CHANNELS 2
+
+/* convert to float from 4-bit (3.1) fixed-point
+ * the always-negative value is stored positive, so make it negative */
+#define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
+
 typedef struct HDCDContext {
 const AVClass *class;
-hdcd_state_t state[2];
+hdcd_state_t state[HDCD_MAX_CHANNELS];
 
+/* use hdcd_*_stereo() functions to process both channels together.
+ * -af hdcd=process_stereo=0 for off
+ * -af hdcd=process_stereo=1 for on
+ * default is HDCD_PROCESS_STEREO_DEFAULT */
+int process_stereo;
 /* always extend peaks above -3dBFS even if PE isn't signaled
  * -af hdcd=force_pe=0 for off
  * -af hdcd=force_pe=1 for on
@@ -875,6 +887,7 @@ typedef struct HDCDContext {
 
 AVFilterContext *fctx; /* filter context for logging errors */
 int sample_count;  /* used in error logging */
+int val_target_gain;   /* last matching target_gain in both channels */
 
 /* User information/stats */
 int hdcd_detected;
@@ -886,9 +899,11 @@ typedef struct HDCDContext {
 
 #define OFFSET(x) offsetof(HDCDContext, x)
 static const AVOption hdcd_options[] = {
+{ "process_stereo", "Process stereo channels together. Only apply 
target_gain when both channels match.",
+OFFSET(process_stereo), AV_OPT_TYPE_INT, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, 0 },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, 0 },
- {NULL}
+{NULL}
 };
 
 AVFILTER_DEFINE_CLASS(hdcd);
@@ -915,12 +930,10 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->code_counterB_checkfails = 0;
 state->code_counterC = 0;
 state->code_counterC_unmatched = 0;
-
 state->count_peak_extend = 0;
 state->count_transient_filter = 0;
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
-
 state->count_sustain_expired = -1;
 }
 
@@ -1037,6 +1050,76 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t 
*state, int *flag, cons
 return result;
 }
 
+static int hdcd_integrate_stereo(HDCDContext *ctx, int *flag, const int32_t 
*samples, int count)
+{
+uint32_t bits[2] = {0, 0};
+int result;
+int i;
+*flag = 0;
+
+/* result = min(count, s0ra, s1ra) */
+result = FFMIN(ctx->state[0].readahead, count);
+result = FFMIN(ctx->state[1].readahead, result);
+
+for (i = result - 1; i >= 0; i--) {
+bits[0] |= (*(samples++) & 1) << i;
+bits[1] |= (*(samples++) & 1) << i;
+}
+
+for (i = 0; i < 2; i++) {
+ctx->state[i].window = (ctx->state[i].window << result) | bits[i];
+ctx->state[i].readahead -= result;
+
+if (ctx->state[i].readahead == 0) {
+uint32_t wbits = (ctx->state[i].window ^ ctx->state[i].window >> 5 
^ ctx->state[i].window >> 23);
+if (ctx->state[i].arg) {
+switch (hdcd_code(wbits, >state[i].control)) {
+case HDCD_CODE_A:
+*flag |= i+1;
+ctx->state[i].code_counterA++;
+break;
+case HDCD_CODE_B:
+*flag |= i+1;
+ctx->state[i].code_counterB++;
+break;
+case HDCD_CODE_A_ALMOST:
+ctx->state[i].code_counterA_almost++;
+av_log(ctx->fctx, AV_LOG_VERBOSE,
+"hdcd error: Control A almost: 0x%02x near %d\n", 
wbits & 0xff, ctx->sample_count);
+break;
+case HDCD_CODE_B_CHECKFAIL:
+ctx->state[i].code_counterB_checkfails++;
+av_log(ct

[FFmpeg-devel] af_hdcd: add flags to AVOption defs

2016-08-01 Thread Burt P
Fix for options not showing up in ffmpeg --help filter=hdcd

Apply after the earlier set of 7 patches where options were
introduced.

--
Burt

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd: add flags to AVOption defs

2016-08-01 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 2d7fe8d..7c90861 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -903,11 +903,12 @@ typedef struct HDCDContext {
 } HDCDContext;
 
 #define OFFSET(x) offsetof(HDCDContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption hdcd_options[] = {
 { "process_stereo", "Process stereo channels together. Only apply 
target_gain when both channels match.",
-OFFSET(process_stereo), AV_OPT_TYPE_INT, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, 0 },
+OFFSET(process_stereo), AV_OPT_TYPE_INT, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
-OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, 0 },
+OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, A },
 {NULL}
 };
 
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] MAINTAINERS: Add myself for af_hdcd

2016-07-31 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6d4c9f9..932e6fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -308,6 +308,7 @@ Filters:
   af_chorus.c   Paul B Mahol
   af_compand.c  Paul B Mahol
   af_firequalizer.c Muhammad Faiz
+  af_hdcd.c     Burt P.
   af_ladspa.c   Paul B Mahol
   af_loudnorm.c Kyle Swanson
   af_pan.c  Nicolas George
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/7] af_hdcd: Improve error detection logging

2016-07-29 Thread Burt P
* Moves the filter context member out of state and into HDCDContext
* More useful information when an error is detected
* Gives a location near where the error was detected

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 34 +++---
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 8498b35..6040400 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -849,8 +849,6 @@ typedef struct {
 /* occurences of code detect timer expiring without detecting
  * a code. -1 for timer never set. */
 int count_sustain_expired;
-
-AVFilterContext *fctx; /* filter context for logging errors */
 } hdcd_state_t;
 
 typedef enum {
@@ -869,6 +867,9 @@ typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
 
+AVFilterContext *fctx; /* filter context for logging errors */
+int sample_count;  /* used in error logging */
+
 /* User information/stats */
 int hdcd_detected;
 int det_errors;/* detectable errors */
@@ -923,7 +924,7 @@ static void hdcd_update_info(hdcd_state_t *state)
 state->max_gain = FFMAX(state->max_gain, (state->control & 15));
 }
 
-static int hdcd_integrate(hdcd_state_t *state, int *flag, const int32_t 
*samples, int count, int stride)
+static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t *state, int *flag, 
const int32_t *samples, int count, int stride)
 {
 uint32_t bits = 0;
 int result = FFMIN(state->readahead, count);
@@ -954,8 +955,8 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 } else {
 /* one of bits 3, 6, or 7 was not 0 */
 state->code_counterA_almost++;
-av_log(state->fctx, AV_LOG_VERBOSE,
-"hdcd error: Control A almost: 0x%08x\n", bits);
+av_log(ctx->fctx, AV_LOG_VERBOSE,
+"hdcd error: Control A almost: 0x%02x near %d\n", bits & 
0xff, ctx->sample_count);
 }
 } else if ((bits & 0xa006) == 0xa006) {
 /* B: 8-bit code, 8-bit XOR check */
@@ -968,14 +969,14 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 } else {
 /* XOR check failed */
 state->code_counterB_checkfails++;
-av_log(state->fctx, AV_LOG_VERBOSE,
-"hdcd error: Control B check failed: 0x%08x\n", bits);
+av_log(ctx->fctx, AV_LOG_VERBOSE,
+   "hdcd error: Control B check failed: 0x%04x (0x%02x vs 
0x%02x) near %d\n", bits & 0x, (bits & 0xff00) >> 8, ~bits & 0xff, 
ctx->sample_count);
 }
 } else {
 /* told to look for a code, but didn't match one */
 state->code_counterC_unmatched++;
-av_log(state->fctx, AV_LOG_VERBOSE,
-"hdcd error: Unmatched code: 0x%08x\n", bits);
+av_log(ctx->fctx, AV_LOG_VERBOSE,
+   "hdcd error: Unmatched code: 0x%08x near %d\n", bits, 
ctx->sample_count);
 }
 if (*flag) hdcd_update_info(state);
 state->arg = 0;
@@ -1002,7 +1003,7 @@ static void hdcd_sustain_reset(hdcd_state_t *state)
 state->count_sustain_expired = 0;
 }
 
-static int hdcd_scan(hdcd_state_t *state, const int32_t *samples, int max, int 
stride)
+static int hdcd_scan(HDCDContext *ctx, hdcd_state_t *state, const int32_t 
*samples, int max, int stride)
 {
 int cdt_active = 0;
 /* code detect timer */
@@ -1018,7 +1019,7 @@ static int hdcd_scan(hdcd_state_t *state, const int32_t 
*samples, int max, int s
 result = 0;
 while (result < max) {
 int flag;
-int consumed = hdcd_integrate(state, , samples, max - result, 
stride);
+int consumed = hdcd_integrate(ctx, state, , samples, max - 
result, stride);
 result += consumed;
 if (flag > 0) {
 /* reset timer if code detected in channel */
@@ -1092,7 +1093,7 @@ static int hdcd_envelope(int32_t *samples, int count, int 
stride, int gain, int
 return gain;
 }
 
-static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int 
stride)
+static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t 
*samples, int count, int stride)
 {
 int32_t *samples_end = samples + count * stride;
 int gain = state->running_gain;
@@ -1105,7 +1106,7 @@ static void hdcd_process(hdcd_state_t *state, int32_t 
*samples, int count, int s
 int run;
 
 av_assert0(samples + lead * stride + stride * (count - lead) <= 
samples_end);
-run = hdcd_scan(state, samples + lead * stride, count - lead, stride) 
+ lead;
+run = hdcd_scan(ctx, state, samples + lead *

[FFmpeg-devel] [PATCH 4/7] af_hdcd: add force_pe filter option

2016-07-29 Thread Burt P
Used to attempt replication of some results from
http://www.audiomisc.co.uk/HFN/HDCD/Examined.html
May not be generally useful, defaults to off.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 6040400..aeb65eb 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -867,6 +867,12 @@ typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
 
+/* always extend peaks above -3dBFS even if PE isn't signaled
+ * -af hdcd=force_pe=0 for off
+ * -af hdcd=force_pe=1 for on
+ * default is off */
+int force_pe;
+
 AVFilterContext *fctx; /* filter context for logging errors */
 int sample_count;  /* used in error logging */
 
@@ -878,7 +884,10 @@ typedef struct HDCDContext {
 float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */
 } HDCDContext;
 
+#define OFFSET(x) offsetof(HDCDContext, x)
 static const AVOption hdcd_options[] = {
+{ "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
+OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, 0 },
  {NULL}
 };
 
@@ -1093,14 +1102,21 @@ static int hdcd_envelope(int32_t *samples, int count, 
int stride, int gain, int
 return gain;
 }
 
+/* extract fields from control code */
+static void hdcd_control(HDCDContext *ctx, hdcd_state_t *state, int 
*peak_extend, int *target_gain)
+{
+*peak_extend = (ctx->force_pe || state->control & 16);
+*target_gain = (state->control & 15) << 7;
+}
+
 static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t 
*samples, int count, int stride)
 {
 int32_t *samples_end = samples + count * stride;
 int gain = state->running_gain;
-int peak_extend = (state->control & 16);
-int target_gain = (state->control & 15) << 7;
+int peak_extend, target_gain;
 int lead = 0;
 
+hdcd_control(ctx, state, _extend, _gain);
 while (count > lead) {
 int envelope_run;
 int run;
@@ -1115,8 +1131,7 @@ static void hdcd_process(HDCDContext *ctx, hdcd_state_t 
*state, int32_t *samples
 samples += envelope_run * stride;
 count -= envelope_run;
 lead = run - envelope_run;
-peak_extend = (state->control & 16);
-target_gain = (state->control & 15) << 7;
+hdcd_control(ctx, state, _extend, _gain);
 }
 if (lead > 0) {
 av_assert0(samples + lead * stride <= samples_end);
@@ -1283,6 +1298,9 @@ static av_cold int init(AVFilterContext *ctx)
 hdcd_reset(>state[c], 44100);
 }
 
+av_log(ctx, AV_LOG_VERBOSE, "Force PE: %s\n",
+(s->force_pe) ? "on" : "off");
+
 return 0;
 }
 
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/7] af_hdcd: give cdt expired counter a value for never set

2016-07-29 Thread Burt P
The counter is now -1 if the code detect timer was never set,
and 0 if it was set but never expired.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index b860077..8498b35 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -846,7 +846,9 @@ typedef struct {
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
-int count_sustain_expired;/* occurences of code detect timer expiring 
without detecting a code */
+/* occurences of code detect timer expiring without detecting
+ * a code. -1 for timer never set. */
+int count_sustain_expired;
 
 AVFilterContext *fctx; /* filter context for logging errors */
 } hdcd_state_t;
@@ -909,7 +911,7 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
 
-state->count_sustain_expired = 0;
+state->count_sustain_expired = -1;
 }
 
 /* update the user info/counters */
@@ -991,6 +993,15 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 return result;
 }
 
+static void hdcd_sustain_reset(hdcd_state_t *state)
+{
+state->sustain = state->sustain_reset;
+/* if this is the first reset then change
+ * from never set, to never expired */
+if (state->count_sustain_expired == -1)
+state->count_sustain_expired = 0;
+}
+
 static int hdcd_scan(hdcd_state_t *state, const int32_t *samples, int max, int 
stride)
 {
 int cdt_active = 0;
@@ -1011,7 +1022,7 @@ static int hdcd_scan(hdcd_state_t *state, const int32_t 
*samples, int max, int s
 result += consumed;
 if (flag > 0) {
 /* reset timer if code detected in channel */
-state->sustain = state->sustain_reset;
+hdcd_sustain_reset(state);
 break;
 }
 samples += consumed * stride;
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/7] af_hdcd: fix a minor annoyance

2016-07-29 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 6f3eb1e..b860077 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -23,12 +23,12 @@
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
 
 /*
   Original code reverse engineered from HDCD decoder library by Christopher 
Key,
   which was likely reverse engineered from Windows Media Player.
-*/
+ */
 
 /*
   HDCD is High Definition Compatible Digital
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 6/7] af_hdcd: Process stereo channels together, fix #5727

2016-07-29 Thread Burt P
Issue #5727: gain adjustment should only be applied if matching
gain value from a valid packet in both channels. The existing functions process
each channel separately, so it was not possible.

* New versions of hdcd_process(), hdcd_scan(), hdcd_integrate() named
  hdcd_*_stereo() that process both channels together.
* target_gain applied will be the last matching target_gain.
* The old single channel functions remain as an option. They can be
  used by: -af hdcd=process_stereo=0.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 287 +++---
 1 file changed, 250 insertions(+), 37 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 902827e..d46c7bc 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -863,10 +863,22 @@ const char* pe_str[] = {
 "enabled permanently"
 };
 
+#define HDCD_PROCESS_STEREO_DEFAULT 1
+#define HDCD_MAX_CHANNELS 2
+
+/* convert to float from 4-bit (3.1) fixed-point
+ * the always-negative value is stored positive, so make it negative */
+#define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0
+
 typedef struct HDCDContext {
 const AVClass *class;
-hdcd_state_t state[2];
+hdcd_state_t state[HDCD_MAX_CHANNELS];
 
+/* use hdcd_*_stereo() functions to process both channels together.
+ * -af hdcd=process_stereo=0 for off
+ * -af hdcd=process_stereo=1 for on
+ * default is HDCD_PROCESS_STEREO_DEFAULT */
+int process_stereo;
 /* always extend peaks above -3dBFS even if PE isn't signaled
  * -af hdcd=force_pe=0 for off
  * -af hdcd=force_pe=1 for on
@@ -875,6 +887,7 @@ typedef struct HDCDContext {
 
 AVFilterContext *fctx; /* filter context for logging errors */
 int sample_count;  /* used in error logging */
+int val_target_gain;   /* last matching target_gain in both channels */
 
 /* User information/stats */
 int hdcd_detected;
@@ -886,9 +899,11 @@ typedef struct HDCDContext {
 
 #define OFFSET(x) offsetof(HDCDContext, x)
 static const AVOption hdcd_options[] = {
+{ "process_stereo", "Process stereo channels together. Only apply 
target_gain when both channels match.",
+OFFSET(process_stereo), AV_OPT_TYPE_INT, { .i64 = 
HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, 0 },
 { "force_pe", "Always extend peaks above -3dBFS even when PE is not 
signaled.",
 OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, 0 },
- {NULL}
+{NULL}
 };
 
 AVFILTER_DEFINE_CLASS(hdcd);
@@ -915,12 +930,10 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->code_counterB_checkfails = 0;
 state->code_counterC = 0;
 state->code_counterC_unmatched = 0;
-
 state->count_peak_extend = 0;
 state->count_transient_filter = 0;
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
-
 state->count_sustain_expired = -1;
 }
 
@@ -1037,6 +1050,76 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t 
*state, int *flag, cons
 return result;
 }
 
+static int hdcd_integrate_stereo(HDCDContext *ctx, int *flag, const int32_t 
*samples, int count)
+{
+uint32_t bits[2] = {0, 0};
+int result;
+int i;
+*flag = 0;
+
+/* result = min(count, s0ra, s1ra) */
+result = FFMIN(ctx->state[0].readahead, count);
+result = FFMIN(ctx->state[1].readahead, result);
+
+for (i = result - 1; i >= 0; i--) {
+bits[0] |= (*(samples++) & 1) << i;
+bits[1] |= (*(samples++) & 1) << i;
+}
+
+for (i = 0; i < 2; i++) {
+ctx->state[i].window = (ctx->state[i].window << result) | bits[i];
+ctx->state[i].readahead -= result;
+
+if (ctx->state[i].readahead == 0) {
+uint32_t wbits = (ctx->state[i].window ^ ctx->state[i].window >> 5 
^ ctx->state[i].window >> 23);
+if (ctx->state[i].arg) {
+switch (hdcd_code(wbits, >state[i].control)) {
+case HDCD_CODE_A:
+*flag |= i+1;
+ctx->state[i].code_counterA++;
+break;
+case HDCD_CODE_B:
+*flag |= i+1;
+ctx->state[i].code_counterB++;
+break;
+case HDCD_CODE_A_ALMOST:
+ctx->state[i].code_counterA_almost++;
+av_log(ctx->fctx, AV_LOG_VERBOSE,
+"hdcd error: Control A almost: 0x%02x near %d\n", 
wbits & 0xff, ctx->sample_count);
+break;
+case HDCD_CODE_B_CHECKFAIL:
+ctx->state[i].code_counterB_checkfails++;
+av_log(ctx->fctx, AV_LOG_VERBOSE,
+

[FFmpeg-devel] [PATCH 0/7] fix(v2) for #5727 split up, plus other things

2016-07-29 Thread Burt P
Here is a set with the earlier patch split into smaller patches.
Added to the old version is hdcd_control_stereo() that logs 
information about the mismatched target_gain so that problem samples
can be found more easily.

Also, a patch for warning about problems in the AVFilterLink chain.

Thanks for comments.

--
Burt

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 0/1] af_hdcd: Process stereo channels together, fix #5727

2016-07-27 Thread Burt P.
> My suggestion is that you send your public key to
> Michael and commit yourself including adding yourself
> as maintainer of hdcd.

I don't know enough about what that would mean. I'm also not
an expert user of git.

>> One strange case is John Mellencamp - [1994] Mr. Happy Go Lucky
>> 06. Emotional Love, where there is one extra HDCD packet in one
>> channel, and that target_gain value ends up being ignored.
>
> Is this a regression against the code in current git head?
> Or just a (possibly) unsolved issue?

This patch causes the target_gain in that packet to be ignored, where
before it would not have been. This is correct, however, if you're trying
to replicate HDCD decoding as described in the paper mentioned in #5727.
Although, aside from being unmatched in the other channel, the packet
appears completely legit. Its just a weird example where the output is
different with the new code. Most of the time the two processing modes
output is exactly the same.

>> This patch is against master, so it also includes the changes in an
>> earlier (not yet applied) patch set for HDCD detection, PE mode,
>> cdt counter, and code comments.
>
> Please split the patches as much as it makes sense.
>

Those other patches have been applied today. I'll split this one up and
resubmit as a set.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd: Process stereo channels together, fix #5727

2016-07-25 Thread Burt P
Issue #5727: gain adjustment should only be applied if matching
gain value from a valid packet in both channels. The existing functions process
each channel separately, so it was not possible.

* New versions of hdcd_process(), hdcd_scan(), hdcd_integrate() named
  hdcd_*_stereo() that process both channels together.
* target_gain applied will be the last matching target_gain.
* The old single channel functions remain as an option. They can be used
  by filter option: -af hdcd=process_stereo=0.
* Some code common to both sets has been moved into own functions:
  hdcd_code(), hdcd_control(), hdcd_sustain_reset().
* This is against master, so it also includes the changes in an earlier
  patch set for HDCD detection, PE mode, cdt counter, and code comments.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 463 +-
 1 file changed, 386 insertions(+), 77 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 6f0db71..725b697 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -23,12 +23,12 @@
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
 
 /*
   Original code reverse engineered from HDCD decoder library by Christopher 
Key,
   which was likely reverse engineered from Windows Media Player.
-*/
+ */
 
 /*
   HDCD is High Definition Compatible Digital
@@ -818,44 +818,88 @@ static const int32_t gaintab[] = {
 
 typedef struct {
 uint64_t window;
-unsigned char readahead, arg, control;
-int running_gain;
-unsigned sustain, sustain_reset;
-int code_counterA;
-int code_counterA_almost; /* looks like an A code, but a bit expected to 
be 0 is 1 */
-int code_counterB;
+unsigned char readahead;
+
+/* arg is set when a packet prefix is found.
+ * control is the active control code, where
+ * bit 0-3: target_gain, 4-bit (3.1) fixed-point value
+ * bit 4  : peak_extend
+ * bit 5  : transient_filter
+ * bit 6,7: always zero */
+unsigned char arg, control;
+unsigned sustain, sustain_reset; /* code detect timer */
+
+int running_gain; /* 11-bit (3.8) fixed point, extended from target_gain */
+
+/* counters */
+int code_counterA;/* 8-bit format packet */
+int code_counterA_almost; /* looks like an A code, but a bit expected 
to be 0 is 1 */
+int code_counterB;/* 16-bit format packet, 8-bit code, 8-bit 
XOR of code */
 int code_counterB_checkfails; /* looks like a B code, but doesn't pass the 
XOR check */
-int code_counterC;
-int code_counterC_unmatched; /* told to look for a code, but didn't find 
one */
-
-/* For user information/stats, pulled up into HDCDContext
- * by filter_frame() */
-int count_peak_extend;
-int count_transient_filter;
+int code_counterC;/* packet prefix was found, expect a code */
+int code_counterC_unmatched;  /* told to look for a code, but didn't find 
one */
+int count_peak_extend;/* valid packets where peak_extend was 
enabled */
+int count_transient_filter;   /* valid packets where filter was detected */
 /* target_gain is a 4-bit (3.1) fixed-point value, always
  * negative, but stored positive.
  * The 16 possible values range from -7.5 to 0.0 dB in
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
-
-AVFilterContext *fctx; /* filter context for logging errors */
+/* occurences of code detect timer expiring without detecting
+ * a code. -1 for timer never set. */
+int count_sustain_expired;
 } hdcd_state_t;
 
+typedef enum {
+HDCD_PE_NEVER=0,
+HDCD_PE_INTERMITTENT =1,
+HDCD_PE_PERMANENT=2
+} hdcd_pe_t;
+
+const char* pe_str[] = {
+"never enabled",
+"enabled intermittently",
+"enabled permanently"
+};
+
+#define HDCD_PROCESS_STEREO_DEFAULT 1
+#define HDCD_MAX_CHANNELS 2
+
 typedef struct HDCDContext {
 const AVClass *class;
-hdcd_state_t state[2];
+hdcd_state_t state[HDCD_MAX_CHANNELS];
+
+/* use hdcd_*_stereo() functions to process both channels together.
+ * -af hdcd=process_stereo=0 for off
+ * -af hdcd=process_stereo=1 for on
+ * default is HDCD_PROCESS_STEREO_DEFAULT */
+int process_stereo;
+/* always extend peaks above -3dBFS even if PE isn't signaled
+ * -af hdcd=force_pe=0 for off
+ * -af hdcd=force_pe=1 for on
+ * default is off */
+int force_pe;
+
+AVFilterContext *fctx; /* filter context for logging errors */
+int sample_count;  /* used in error logging */
+int val_target_gain;   /* last matching target_gain in both channels */
 
 /* User information/stats */
 in

[FFmpeg-devel] [PATCH 0/1] af_hdcd: Process stereo channels together, fix #5727

2016-07-25 Thread Burt P
For review, a fix for #5727. Please test and comment.

I've made new versions of the processing functions that process
stereo channels together so that the rule regarding target_gain can
be implemented. The target_gain used for both channels will now be
the last valid target_gain that matched between channels.

The old single-channel functions are still there, so that testing
is possible, and for compatibility with the original fb2k code.
They can be used by: -af hdcd=process_stereo=0

I've tested several HDCD flac and the majority come out exactly the
same using either path, but there have been a few differences where
control codes do not appear at exactly the same sample, so there is
a few samples of delay before they match up.

One strange case is John Mellencamp - [1994] Mr. Happy Go Lucky
06. Emotional Love, where there is one extra HDCD packet in one
channel, and that target_gain value ends up being ignored.

This patch is against master, so it also includes the changes in an
earlier (not yet applied) patch set for HDCD detection, PE mode,
cdt counter, and code comments.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd: Add counter for cdt expirations

2016-07-24 Thread Burt P
Adds a counter for when the "code detect timer" expired without
finding a valid packet.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 72560db..f265ed9 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -846,6 +846,7 @@ typedef struct {
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
+int count_sustain_expired;/* occurences of code detect timer expiring 
without detecting a code */
 
 AVFilterContext *fctx; /* filter context for logging errors */
 } hdcd_state_t;
@@ -895,6 +896,8 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->count_transient_filter = 0;
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
+
+state->count_sustain_expired = 0;
 }
 
 /* update the user info/counters */
@@ -978,8 +981,11 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 
 static int hdcd_scan(hdcd_state_t *state, const int32_t *samples, int max, int 
stride)
 {
+int cdt_active = 0;
+/* code detect timer */
 int result;
 if (state->sustain > 0) {
+cdt_active = 1;
 if (state->sustain <= max) {
 state->control = 0;
 max = state->sustain;
@@ -992,11 +998,15 @@ static int hdcd_scan(hdcd_state_t *state, const int32_t 
*samples, int max, int s
 int consumed = hdcd_integrate(state, , samples, max - result, 
stride);
 result += consumed;
 if (flag > 0) {
+/* reset timer if code detected in channel */
 state->sustain = state->sustain_reset;
 break;
 }
 samples += consumed * stride;
 }
+/* code detect timer expired */
+if (cdt_active && state->sustain == 0)
+state->count_sustain_expired++;
 return result;
 }
 
@@ -1198,12 +1208,13 @@ static av_cold void uninit(AVFilterContext *ctx)
 hdcd_state_t *state = >state[i];
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: counter A: %d, B: %d, C: 
%d\n", i,
 state->code_counterA, state->code_counterB, 
state->code_counterC);
-av_log(ctx, AV_LOG_VERBOSE, "Channel %d: pe: %d, tf: %d, almost_A: %d, 
checkfail_B: %d, unmatched_C: %d\n", i,
+av_log(ctx, AV_LOG_VERBOSE, "Channel %d: pe: %d, tf: %d, almost_A: %d, 
checkfail_B: %d, unmatched_C: %d, cdt_expired: %d\n", i,
 state->count_peak_extend,
 state->count_transient_filter,
 state->code_counterA_almost,
 state->code_counterB_checkfails,
-state->code_counterC_unmatched);
+state->code_counterC_unmatched,
+state->count_sustain_expired);
 for (j = 0; j <= state->max_gain; j++) {
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: tg %0.1f: %d\n", i, 
GAINTOFLOAT(j), state->gain_counts[j]);
 }
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 4/4] af_hdcd: Report PE as being intermittent or permanent

2016-07-23 Thread Burt P
The Peak Extend feature could be enabled permanently or only
when needed. This is now reported.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 30 ++
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 7c9494d..daaafba 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -851,6 +851,18 @@ typedef struct {
 AVFilterContext *fctx; /* filter context for logging errors */
 } hdcd_state_t;
 
+typedef enum {
+HDCD_PE_NEVER=0,
+HDCD_PE_INTERMITTENT =1,
+HDCD_PE_PERMANENT=2
+} hdcd_pe_t;
+
+const char* pe_str[] = {
+"never enabled",
+"enabled intermittently",
+"enabled permanently"
+};
+
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
@@ -858,7 +870,7 @@ typedef struct HDCDContext {
 /* User information/stats */
 int hdcd_detected;
 int det_errors;/* detectable errors */
-int uses_peak_extend;
+hdcd_pe_t peak_extend;
 int uses_transient_filter; /* detected, but not implemented */
 float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */
 } HDCDContext;
@@ -1114,7 +1126,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 const int16_t *in_data;
 int32_t *out_data;
 int n, c;
-int detect;
+int detect, packets, pe_packets;
 
 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
@@ -1131,18 +1143,28 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 }
 
 detect = 0;
+packets = 0;
+pe_packets = 0;
 s->det_errors = 0;
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
 hdcd_process(state, out_data + c, in->nb_samples, out->channels);
 if (state->sustain) detect++;
-s->uses_peak_extend |= !!state->count_peak_extend;
+packets += state->code_counterA + state->code_counterB;
+pe_packets += state->count_peak_extend;
 s->uses_transient_filter |= !!state->count_transient_filter;
 s->max_gain_adjustment = FFMIN(s->max_gain_adjustment, 
GAINTOFLOAT(state->max_gain));
 s->det_errors += state->code_counterA_almost
 + state->code_counterB_checkfails
 + state->code_counterC_unmatched;
 }
+if (pe_packets) {
+/* if every valid packet has used PE, call it permanent */
+if (packets == pe_packets)
+s->peak_extend = HDCD_PE_PERMANENT;
+else
+s->peak_extend = HDCD_PE_INTERMITTENT;
+} else s->peak_extend = HDCD_PE_NEVER;
 /* HDCD is detected if a valid packet is active in all (both)
  * channels at the same time. */
 if (detect == inlink->channels) s->hdcd_detected = 1;
@@ -1223,7 +1245,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 if (s->hdcd_detected)
 av_log(ctx, AV_LOG_INFO,
 "HDCD detected: yes, peak_extend: %s, max_gain_adj: %0.1f dB, 
transient_filter: %s, detectable errors: %d%s\n",
-(s->uses_peak_extend) ? "enabled" : "never enabled",
+pe_str[s->peak_extend],
 s->max_gain_adjustment,
 (s->uses_transient_filter) ? "detected" : "not detected",
 s->det_errors, (s->det_errors) ? " (try -v verbose)" : ""
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] af_hdcd: Improve HDCD detection

2016-07-23 Thread Burt P.
On Sat, Jul 23, 2016 at 5:41 PM, Michael Niedermayer
 wrote:
>
> this looks like 2 unrelated changes
> one is improving documentation the other is changing ths detect code
> can you split these in 2 patches ?

Ok, I've submitted a new set.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/4] af_hdcd: Add counter for cdt expirations

2016-07-23 Thread Burt P
Adds a counter for when the code detect timer expired without
finding a valid packet.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 72560db..7c9494d 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -846,6 +846,7 @@ typedef struct {
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
+int count_sustain_expired;/* occurances of code detect timer expiring 
without detecting a code */
 
 AVFilterContext *fctx; /* filter context for logging errors */
 } hdcd_state_t;
@@ -895,6 +896,8 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->count_transient_filter = 0;
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
+
+state->count_sustain_expired = 0;
 }
 
 /* update the user info/counters */
@@ -979,7 +982,10 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 static int hdcd_scan(hdcd_state_t *state, const int32_t *samples, int max, int 
stride)
 {
 int result;
+int cdt_active = 0;
+/* code detect timer */
 if (state->sustain > 0) {
+cdt_active = 1;
 if (state->sustain <= max) {
 state->control = 0;
 max = state->sustain;
@@ -992,11 +998,14 @@ static int hdcd_scan(hdcd_state_t *state, const int32_t 
*samples, int max, int s
 int consumed = hdcd_integrate(state, , samples, max - result, 
stride);
 result += consumed;
 if (flag > 0) {
+/* reset timer if code detected in channel */
 state->sustain = state->sustain_reset;
 break;
 }
 samples += consumed * stride;
 }
+/* code detect timer expired */
+if (cdt_active && state->sustain == 0) state->count_sustain_expired++;
 return result;
 }
 
@@ -1198,12 +1207,13 @@ static av_cold void uninit(AVFilterContext *ctx)
 hdcd_state_t *state = >state[i];
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: counter A: %d, B: %d, C: 
%d\n", i,
 state->code_counterA, state->code_counterB, 
state->code_counterC);
-av_log(ctx, AV_LOG_VERBOSE, "Channel %d: pe: %d, tf: %d, almost_A: %d, 
checkfail_B: %d, unmatched_C: %d\n", i,
+av_log(ctx, AV_LOG_VERBOSE, "Channel %d: pe: %d, tf: %d, almost_A: %d, 
checkfail_B: %d, unmatched_C: %d, cdt_expired: %d\n", i,
 state->count_peak_extend,
 state->count_transient_filter,
 state->code_counterA_almost,
 state->code_counterB_checkfails,
-state->code_counterC_unmatched);
+state->code_counterC_unmatched,
+state->count_sustain_expired);
 for (j = 0; j <= state->max_gain; j++) {
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: tg %0.1f: %d\n", i, 
GAINTOFLOAT(j), state->gain_counts[j]);
 }
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/4] af_hdcd: Improve HDCD detection

2016-07-23 Thread Burt P
HDCD is now only considered detected if a valid packet
is active in both channels simultaneously.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 6f0db71..f68a105 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1097,6 +1097,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 const int16_t *in_data;
 int32_t *out_data;
 int n, c;
+int detect;
 
 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
@@ -1112,19 +1113,22 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 out_data[n] = in_data[n];
 }
 
+detect = 0;
 s->det_errors = 0;
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
 hdcd_process(state, out_data + c, in->nb_samples, out->channels);
-
+if (state->sustain) detect++;
 s->uses_peak_extend |= !!state->count_peak_extend;
 s->uses_transient_filter |= !!state->count_transient_filter;
 s->max_gain_adjustment = FFMIN(s->max_gain_adjustment, 
GAINTOFLOAT(state->max_gain));
-s->hdcd_detected |= state->code_counterB || state->code_counterA;
 s->det_errors += state->code_counterA_almost
 + state->code_counterB_checkfails
 + state->code_counterC_unmatched;
 }
+/* HDCD is detected if a valid packet is active in all (both)
+ * channels at the same time. */
+if (detect == inlink->channels) s->hdcd_detected = 1;
 
 av_frame_free();
 return ff_filter_frame(outlink, out);
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/4] af_hdcd: more comments in state struct

2016-07-23 Thread Burt P
Add some comments describing the fields in hdcd_state_t.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index f68a105..72560db 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -818,20 +818,28 @@ static const int32_t gaintab[] = {
 
 typedef struct {
 uint64_t window;
-unsigned char readahead, arg, control;
-int running_gain;
-unsigned sustain, sustain_reset;
-int code_counterA;
-int code_counterA_almost; /* looks like an A code, but a bit expected to 
be 0 is 1 */
-int code_counterB;
+unsigned char readahead;
+
+/* arg is set when a packet prefix is found.
+ * control is the active control code, where
+ * bit 0-3: target_gain, 4-bit (3.1) fixed-point value
+ * bit 4  : peak_extend
+ * bit 5  : transient_filter
+ * bit 6,7: always zero */
+unsigned char arg, control;
+unsigned sustain, sustain_reset; /* code detect timer */
+
+int running_gain; /* 11-bit (3.8) fixed point, extended from target_gain */
+
+/* counters */
+int code_counterA;/* 8-bit format packet */
+int code_counterA_almost; /* looks like an A code, but a bit expected 
to be 0 is 1 */
+int code_counterB;/* 16-bit format packet, 8-bit code, 8-bit 
XOR of code */
 int code_counterB_checkfails; /* looks like a B code, but doesn't pass the 
XOR check */
-int code_counterC;
-int code_counterC_unmatched; /* told to look for a code, but didn't find 
one */
-
-/* For user information/stats, pulled up into HDCDContext
- * by filter_frame() */
-int count_peak_extend;
-int count_transient_filter;
+int code_counterC;/* packet prefix was found, expect a code */
+int code_counterC_unmatched;  /* told to look for a code, but didn't find 
one */
+int count_peak_extend;/* valid packets where peak_extend was 
enabled */
+int count_transient_filter;   /* valid packets where filter was detected */
 /* target_gain is a 4-bit (3.1) fixed-point value, always
  * negative, but stored positive.
  * The 16 possible values range from -7.5 to 0.0 dB in
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 0/4] HDCD filter improvements

2016-07-23 Thread Burt P
I've split an earlier patch as requested, and added a couple more to the set.

--
Burt

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] af_hdcd: Improve HDCD detection

2016-07-23 Thread Burt P.
It does not fix #5727, it only improves the result for the "HDCD
detected" line in the log.

To fix #5727, the code has to be changed to process both channels at
once, so that target_gain of both channels is known for every
processed sample, or at least every segment between HDCD packets. I am
attempting this.

On Fri, Jul 22, 2016 at 1:49 AM, Carl Eugen Hoyos <ceho...@ag.or.at> wrote:
> Burt P  gmail.com> writes:
>
>> HDCD is only "detected" if a valid code is active in both
>> channels simultaneously
>
> Does your patch fix ticket #5727?
> You don't mention this in the ticket...
>
> Thank you for looking at this, Carl Eugen
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel



-- 
Burt
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd: Improve HDCD detection

2016-07-17 Thread Burt P
HDCD is only "detected" if a valid code is active in both
channels simultaneously, as described here:
https://hydrogenaud.io/index.php/topic,79427.msg900371.html#msg900371

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 34 --
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 6f0db71..4b48967 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -818,15 +818,25 @@ static const int32_t gaintab[] = {
 
 typedef struct {
 uint64_t window;
-unsigned char readahead, arg, control;
-int running_gain;
-unsigned sustain, sustain_reset;
-int code_counterA;
-int code_counterA_almost; /* looks like an A code, but a bit expected to 
be 0 is 1 */
-int code_counterB;
+unsigned char readahead;
+
+/* arg is set when a packet prefix is found.
+ * control is the active control code, where
+ * bit 0-3: target_gain, 4-bit (3.1) fixed-point value
+ * bit 4  : peak_extend
+ * bit 5  : transient_filter
+ * bit 6,7: always zero */
+unsigned char arg, control;
+unsigned sustain, sustain_reset; /* code detect timer */
+
+int running_gain; /* 11-bit (3.8) fixed point, extended from target_gain */
+
+int code_counterA;/* 8-bit format packet */
+int code_counterA_almost; /* looks like an A code, but a bit expected 
to be 0 is 1 */
+int code_counterB;/* 16-bit format packet, 8-bit code, 8-bit 
XOR of code */
 int code_counterB_checkfails; /* looks like a B code, but doesn't pass the 
XOR check */
-int code_counterC;
-int code_counterC_unmatched; /* told to look for a code, but didn't find 
one */
+int code_counterC;/* packet prefix was found, expect a code */
+int code_counterC_unmatched;  /* told to look for a code, but didn't find 
one */
 
 /* For user information/stats, pulled up into HDCDContext
  * by filter_frame() */
@@ -1096,7 +1106,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 AVFrame *out;
 const int16_t *in_data;
 int32_t *out_data;
-int n, c;
+int n, c, detect;
 
 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
@@ -1112,6 +1122,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 out_data[n] = in_data[n];
 }
 
+detect = 0;
 s->det_errors = 0;
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
@@ -1120,11 +1131,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 s->uses_peak_extend |= !!state->count_peak_extend;
 s->uses_transient_filter |= !!state->count_transient_filter;
 s->max_gain_adjustment = FFMIN(s->max_gain_adjustment, 
GAINTOFLOAT(state->max_gain));
-s->hdcd_detected |= state->code_counterB || state->code_counterA;
+if (state->sustain) detect++;
 s->det_errors += state->code_counterA_almost
 + state->code_counterB_checkfails
 + state->code_counterC_unmatched;
 }
+/* HDCD is detected if a valid packet is active in all (both)
+ * channels at the same time. */
+if (detect == inlink->channels) s->hdcd_detected = 1;
 
 av_frame_free();
 return ff_filter_frame(outlink, out);
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] fate: Add HDCD filter tests for false positive and error detection

2016-07-14 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 tests/fate-run.sh   |  3 ++-
 tests/fate/filter-audio.mak | 12 
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index c898695..5841b0c 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -328,13 +328,14 @@ if [ $err -gt 128 ]; then
 test "${sig}" = "${sig%[!A-Za-z]*}" || unset sig
 fi
 
-if test -e "$ref" || test $cmp = "oneline" ; then
+if test -e "$ref" || test $cmp = "oneline" || test $cmp = "grep" ; then
 case $cmp in
 diff)   diff -u -b "$ref" "$outfile">$cmpfile ;;
 rawdiff)diff -u"$ref" "$outfile">$cmpfile ;;
 oneoff) oneoff "$ref" "$outfile">$cmpfile ;;
 stddev) stddev "$ref" "$outfile">$cmpfile ;;
 oneline)oneline"$ref" "$outfile">$cmpfile ;;
+grep)   grep   "$ref" "$errfile">$cmpfile ;;
 null)   cat   "$outfile">$cmpfile ;;
 esac
 cmperr=$?
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 1a52320..cba2bca 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -199,6 +199,18 @@ fate-filter-hdcd: CMD = md5 -i $(SRC) -af hdcd -f s24le
 fate-filter-hdcd: CMP = oneline
 fate-filter-hdcd: REF = 5db465a58d2fd0d06ca944b883b33476
 
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-false-positive
+fate-filter-hdcd-false-positive: SRC = 
$(TARGET_SAMPLES)/filter/hdcd-false-positive.flac
+fate-filter-hdcd-false-positive: CMD = md5 -i $(SRC) -af hdcd -f s24le
+fate-filter-hdcd-false-positive: CMP = grep
+fate-filter-hdcd-false-positive: REF = HDCD detected: no
+
+FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, HDCD, FLAC, FLAC, PCM_S24LE, 
PCM_S24LE) += fate-filter-hdcd-detect-errors
+fate-filter-hdcd-detect-errors: SRC = 
$(TARGET_SAMPLES)/filter/hdcd-encoding-errors.flac
+fate-filter-hdcd-detect-errors: CMD = md5 -i $(SRC) -af hdcd -f s24le
+fate-filter-hdcd-detect-errors: CMP = grep
+fate-filter-hdcd-detect-errors: REF = detectable errors: [1-9]
+
 FATE_AFILTER-yes += fate-filter-formats
 fate-filter-formats: libavfilter/tests/formats$(EXESUF)
 fate-filter-formats: CMD = run libavfilter/tests/formats
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/5] af_hdcd: fewer false positives by ignoring code_counterC in HDCD detection

2016-07-12 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 73a0b93..48f87f6 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1094,7 +1094,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 s->uses_peak_extend |= !!state->count_peak_extend;
 s->uses_transient_filter |= !!state->count_transient_filter;
 s->max_gain_adjustment = FFMIN(s->max_gain_adjustment, 
GAINTOFLOAT(state->max_gain));
-s->hdcd_detected |= state->code_counterC || state->code_counterB || 
state->code_counterA;
+s->hdcd_detected |= state->code_counterB || state->code_counterA;
 }
 
 av_frame_free();
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/5] af_hdcd: only hdcd_update_info() when something changes

2016-07-12 Thread Burt P
Only call hdcd_update_info() when the control code changes
instead of every frame, so the counters are more meaningful.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 34 +-
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 48f87f6..4104935 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -835,7 +835,6 @@ typedef struct {
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
-int cb6, cb7; /* watch bits 6 and 7 of the control code, for curiosity */
 } hdcd_state_t;
 
 typedef struct HDCDContext {
@@ -879,8 +878,15 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->count_transient_filter = 0;
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
-state->cb6 = 0;
-state->cb7 = 0;
+}
+
+/* update the user info/counters */
+static void hdcd_update_info(hdcd_state_t *state)
+{
+if (state->control & 16) state->count_peak_extend++;
+if (state->control & 32) state->count_transient_filter++;
+state->gain_counts[state->control & 15]++;
+state->max_gain = FFMAX(state->max_gain, (state->control & 15));
 }
 
 static int hdcd_integrate(hdcd_state_t *state, int *flag, const int32_t 
*samples, int count, int stride)
@@ -913,6 +919,7 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 *flag = 1;
 state->code_counterB++;
 }
+if (*flag) hdcd_update_info(state);
 state->arg = 0;
 }
 if (bits == 0x7e0fa005 || bits == 0x7e0fa006) {
@@ -1011,18 +1018,6 @@ static int hdcd_envelope(int32_t *samples, int count, 
int stride, int gain, int
 return gain;
 }
 
-/* update the user info/flags */
-static void hdcd_update_info(hdcd_state_t *state)
-{
-if (state->control & 16) state->count_peak_extend++;
-if (state->control & 32) state->count_transient_filter++;
-state->gain_counts[state->control & 15]++;
-state->max_gain = FFMAX(state->max_gain, (state->control & 15));
-
-if (state->control & 64) state->cb6++;
-if (state->control & 128) state->cb7++;
-}
-
 static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int 
stride)
 {
 int32_t *samples_end = samples + count * stride;
@@ -1031,8 +1026,6 @@ static void hdcd_process(hdcd_state_t *state, int32_t 
*samples, int count, int s
 int target_gain = (state->control & 15) << 7;
 int lead = 0;
 
-hdcd_update_info(state);
-
 while (count > lead) {
 int envelope_run;
 int run;
@@ -1049,7 +1042,6 @@ static void hdcd_process(hdcd_state_t *state, int32_t 
*samples, int count, int s
 lead = run - envelope_run;
 peak_extend = (state->control & 16);
 target_gain = (state->control & 15) << 7;
-hdcd_update_info(state);
 }
 if (lead > 0) {
 av_assert0(samples + lead * stride <= samples_end);
@@ -1157,10 +1149,10 @@ static av_cold void uninit(AVFilterContext *ctx)
 hdcd_state_t *state = >state[i];
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: counter A: %d, B: %d, C: 
%d\n", i, state->code_counterA,
 state->code_counterB, state->code_counterC);
-av_log(ctx, AV_LOG_VERBOSE, "Channel %d: c(pe): %d, c(tf): %d, cb6: 
%d, cb7: %d\n", i,
-state->count_peak_extend, state->count_transient_filter, 
state->cb6, state->cb7);
+av_log(ctx, AV_LOG_VERBOSE, "Channel %d: cpe: %d, ctf: %d\n", i,
+state->count_peak_extend, state->count_transient_filter);
 for (j = 0; j <= state->max_gain; j++) {
-av_log(ctx, AV_LOG_VERBOSE, "Channel %d: tg %0.1f - %d\n", i, 
GAINTOFLOAT(j), state->gain_counts[j]);
+av_log(ctx, AV_LOG_VERBOSE, "Channel %d: tg %0.1f: %d\n", i, 
GAINTOFLOAT(j), state->gain_counts[j]);
 }
 }
 
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 5/5] af_hdcd: detect and report encoding errors and oddities

2016-07-12 Thread Burt P
Count and report when a code is signaled but fails to match a known pattern.
For example try Līve - Secret Samadhi.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 73 ---
 1 file changed, 58 insertions(+), 15 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 8acbdda..6f0db71 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -822,8 +822,11 @@ typedef struct {
 int running_gain;
 unsigned sustain, sustain_reset;
 int code_counterA;
+int code_counterA_almost; /* looks like an A code, but a bit expected to 
be 0 is 1 */
 int code_counterB;
+int code_counterB_checkfails; /* looks like a B code, but doesn't pass the 
XOR check */
 int code_counterC;
+int code_counterC_unmatched; /* told to look for a code, but didn't find 
one */
 
 /* For user information/stats, pulled up into HDCDContext
  * by filter_frame() */
@@ -835,6 +838,8 @@ typedef struct {
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
+
+AVFilterContext *fctx; /* filter context for logging errors */
 } hdcd_state_t;
 
 typedef struct HDCDContext {
@@ -843,6 +848,7 @@ typedef struct HDCDContext {
 
 /* User information/stats */
 int hdcd_detected;
+int det_errors;/* detectable errors */
 int uses_peak_extend;
 int uses_transient_filter; /* detected, but not implemented */
 float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */
@@ -871,8 +877,11 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->sustain_reset = rate * 10;
 
 state->code_counterA = 0;
+state->code_counterA_almost = 0;
 state->code_counterB = 0;
+state->code_counterB_checkfails = 0;
 state->code_counterC = 0;
+state->code_counterC_unmatched = 0;
 
 state->count_peak_extend = 0;
 state->count_transient_filter = 0;
@@ -909,15 +918,39 @@ static int hdcd_integrate(hdcd_state_t *state, int *flag, 
const int32_t *samples
 bits = (state->window ^ state->window >> 5 ^ state->window >> 23);
 
 if (state->arg) {
-if ((bits & 0xffc8) == 0x0fa00500) {
-state->control = (bits & 255) + (bits & 7);
-*flag = 1;
-state->code_counterA++;
-}
-if (((bits ^ (~bits >> 8 & 255)) & 0x00ff) == 0xa006) {
-state->control = bits >> 8 & 255;
-*flag = 1;
-state->code_counterB++;
+if ((bits & 0x0fa00500) == 0x0fa00500) {
+/* A: 8-bit code */
+if ((bits & 0xc8) == 0) {
+/*   [..pt ]
+ * 0x0fa005[..] -> 0b[00.. 0...], gain part doubled */
+state->control = (bits & 255) + (bits & 7);
+*flag = 1;
+state->code_counterA++;
+} else {
+/* one of bits 3, 6, or 7 was not 0 */
+state->code_counterA_almost++;
+av_log(state->fctx, AV_LOG_VERBOSE,
+"hdcd error: Control A almost: 0x%08x\n", bits);
+}
+} else if ((bits & 0xa006) == 0xa006) {
+/* B: 8-bit code, 8-bit XOR check */
+if (((bits ^ (~bits >> 8 & 255)) & 0x00ff) == 0xa006) {
+/*  check:   [..pt  ~(..pt )]
+ * 0xa006[] -> 0b[      ] */
+state->control = bits >> 8 & 255;
+*flag = 1;
+state->code_counterB++;
+} else {
+/* XOR check failed */
+state->code_counterB_checkfails++;
+av_log(state->fctx, AV_LOG_VERBOSE,
+"hdcd error: Control B check failed: 0x%08x\n", bits);
+}
+} else {
+/* told to look for a code, but didn't match one */
+state->code_counterC_unmatched++;
+av_log(state->fctx, AV_LOG_VERBOSE,
+"hdcd error: Unmatched code: 0x%08x\n", bits);
 }
 if (*flag) hdcd_update_info(state);
 state->arg = 0;
@@ -1079,6 +1112,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 out_data[n] = in_data[n];
 }
 
+s->det_errors = 0;
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
 hdcd_process(state, out_data + c, in->nb_samples, out->channels);
@@ -1087,6 +1121,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 s->uses_transient_filter |= !!state->count_transient_filter;
 s->max_gain_adjustment = FFMIN(s->m

[FFmpeg-devel] [PATCH 4/5] af_hdcd: don't log full HDCD stats if HDCD was not detected

2016-07-12 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 4104935..8acbdda 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1157,13 +1157,15 @@ static av_cold void uninit(AVFilterContext *ctx)
 }
 
 /* log the HDCD decode information */
-av_log(ctx, AV_LOG_INFO,
-"HDCD detected: %s, peak_extend: %s, max_gain_adj: %0.1f dB, 
transient_filter: %s\n",
-(s->hdcd_detected) ? "yes" : "no",
-(s->uses_peak_extend) ? "enabled" : "never enabled",
-s->max_gain_adjustment,
-(s->uses_transient_filter) ? "detected" : "not detected"
-);
+if (s->hdcd_detected)
+av_log(ctx, AV_LOG_INFO,
+"HDCD detected: yes, peak_extend: %s, max_gain_adj: %0.1f dB, 
transient_filter: %s\n",
+(s->uses_peak_extend) ? "enabled" : "never enabled",
+s->max_gain_adjustment,
+(s->uses_transient_filter) ? "detected" : "not detected"
+);
+else
+av_log(ctx, AV_LOG_INFO, "HDCD detected: no\n");
 }
 
 static av_cold int init(AVFilterContext *ctx)
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 0/5] Split up HDCD filter patch

2016-07-12 Thread Burt P
This is the previous patch split into smaller patches, as requested.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] af_hdcd.c: only hdcd_update_info() when something changes, add error detection

2016-07-11 Thread Burt P.
Only call hdcd_update_info() when the control code changes
instead of every frame, so the counters are more meaningful.

Also, adds some basic error detection. After scanning through
about 30 HDCD-encoded CD's I've found errors where a code
is signaled, but then fails to match one of the patterns, so
it is ignored. Often, it is very close to a code, differing
by only one bit. I don't know enough to say whether it is
using some unknown feature of HDCD that this filter doesn't
know about, or if there was just an error in the encoding.
I've added some comments so that it should be easier for
others to examine.

An example with many errors is Līve - Secret Samadhi, if
anyone wants to look into it.

Patch is attached.
Any comments would be appreciated.
From 63a2736dd8444fe64d8c5bc885d61979bfe93f6b Mon Sep 17 00:00:00 2001
From: Burt P <pbu...@gmail.com>
Date: Mon, 11 Jul 2016 17:08:20 -0500
Subject: [PATCH] af_hdcd.c: only hdcd_update_info() when something changes,
 add error detection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* hdcd_update_info() when control code changes; counts are more meaningful
* some encoding errors can be detected
* fewer false positives by ignoring code_counterC in HDCD detection
* integrate() renamed hdcd_integrate() to be consistent with the other function names
* some code comments

Try LÄ«ve - Secret Samadhi or John Mellencamp - Mr. Happy Go Lucky for error detection.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 122 --
 1 file changed, 79 insertions(+), 43 deletions(-)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 89012eb..72267d5 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -822,8 +822,11 @@ typedef struct {
 int running_gain;
 unsigned sustain, sustain_reset;
 int code_counterA;
+int code_counterA_almost; /* looks like an A code, but a bit expected to be 0 is 1 */
 int code_counterB;
+int code_counterB_checkfails; /* looks like a B code, but doesn't pass the XOR check */
 int code_counterC;
+int code_counterC_unmatched; /* told to look for a code, but didn't find one */
 
 /* For user information/stats, pulled up into HDCDContext
  * by filter_frame() */
@@ -835,7 +838,6 @@ typedef struct {
  * steps of 0.5, but no value below -6.0 dB should appear. */
 int gain_counts[16]; /* for cursiosity, mostly */
 int max_gain;
-int cb6, cb7; /* watch bits 6 and 7 of the control code, for curiosity */
 } hdcd_state_t;
 
 typedef struct HDCDContext {
@@ -844,6 +846,7 @@ typedef struct HDCDContext {
 
 /* User information/stats */
 int hdcd_detected;
+int det_errors;/* detectable errors */
 int uses_peak_extend;
 int uses_transient_filter; /* detected, but not implemented */
 float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */
@@ -872,18 +875,28 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->sustain_reset = rate * 10;
 
 state->code_counterA = 0;
+state->code_counterA_almost = 0;
 state->code_counterB = 0;
+state->code_counterB_checkfails = 0;
 state->code_counterC = 0;
+state->code_counterC_unmatched = 0;
 
 state->count_peak_extend = 0;
 state->count_transient_filter = 0;
 for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
 state->max_gain = 0;
-state->cb6 = 0;
-state->cb7 = 0;
 }
 
-static int integrate(hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride)
+/* Update the user info/counters */
+static void hdcd_update_info(hdcd_state_t *state)
+{
+if (state->control & 16) state->count_peak_extend++;
+if (state->control & 32) state->count_transient_filter++;
+state->gain_counts[state->control & 15]++;
+state->max_gain = FFMAX(state->max_gain, (state->control & 15));
+}
+
+static int hdcd_integrate(hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride)
 {
 uint32_t bits = 0;
 int result = FFMIN(state->readahead, count);
@@ -903,19 +916,45 @@ static int integrate(hdcd_state_t *state, int *flag, const int32_t *samples, int
 bits = (state->window ^ state->window >> 5 ^ state->window >> 23);
 
 if (state->arg) {
-if ((bits & 0xffc8) == 0x0fa00500) {
-state->control = (bits & 255) + (bits & 7);
-*flag = 1;
-state->code_counterA++;
-}
-if (((bits ^ (~bits >> 8 & 255)) & 0x00ff) == 0xa006) {
-state->control = bits >> 8 & 255;
-*flag = 1;
-state->code_counterB++;
+if ((bits & 0x0fa00500) == 0x0fa00500) {
+/* A: 8-bit code */
+if ((bits & 0xc8) == 0) {

Re: [FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

2016-07-05 Thread Burt P.
Attached is the fourth version of this patch. I've reworked it
a bit to make it cleaner and provide more interesting/useful
information. Also, I've updated the documentation.
This includes the fix to low-level gain adjustment.

Thanks.
From 328b75b0abbc1e760a115c98d6f43dc6ff9a8fa1 Mon Sep 17 00:00:00 2001
From: Burt P <pbu...@gmail.com>
Date: Tue, 5 Jul 2016 12:23:33 -0500
Subject: [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

The new HDCD filter really does nothing to show that it is working or
that HDCD control information was even detected in the stream. This
patch collects information about the decode, like which features were
used, and reports it to the user at the end.

Also,
* Fixes low-level gain adjustment
* Updates the documentation

Signed-off-by: Burt P <pbu...@gmail.com>
---
 doc/filters.texi  | 19 +++--
 libavfilter/af_hdcd.c | 76 +--
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 3cf3d7c..16f315b 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -8427,8 +8427,23 @@ ffplay input.mkv -vf "movie=clut.png, [in] haldclut"
 
 @section hdcd
 
-Decodes high definition audio cd data. 16-Bit PCM stream containing hdcd flags
-is converted to 20-bit PCM stream.
+Decodes High Definition Compatible Digital (HDCD) data. A 16-bit PCM stream with
+embedded HDCD codes is expanded into a 20-bit PCM stream.
+
+The filter supports the Peak Extend and Low-level Gain Adjustment features
+of HDCD, and detects the Transient Filter flag.
+
+@example
+ffmpeg -i HDCD16.flac -af hdcd OUT24.flac
+@end example
+
+When using the filter with wav, note the default encoding for wav is 16-bit, 
+so the resulting 20-bit stream will be truncated back to 16-bit. Use something
+like @command{-acodec pcm_s24le} after the filter to get 24-bit PCM output.
+@example
+ffmpeg -i HDCD16.wav -af hdcd OUT16.wav
+ffmpeg -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav
+@end example
 
 @section hflip
 
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 16bdcb0..89012eb 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -31,7 +31,8 @@
 */
 
 /*
-  More information about high definition audio cds:
+  HDCD is High Definition Compatible Digital
+  More information about HDCD-encoded audio CDs:
   http://www.audiomisc.co.uk/HFN/HDCD/Enigma.html
   http://www.audiomisc.co.uk/HFN/HDCD/Examined.html
  */
@@ -823,11 +824,29 @@ typedef struct {
 int code_counterA;
 int code_counterB;
 int code_counterC;
+
+/* For user information/stats, pulled up into HDCDContext
+ * by filter_frame() */
+int count_peak_extend;
+int count_transient_filter;
+/* target_gain is a 4-bit (3.1) fixed-point value, always
+ * negative, but stored positive.
+ * The 16 possible values range from -7.5 to 0.0 dB in
+ * steps of 0.5, but no value below -6.0 dB should appear. */
+int gain_counts[16]; /* for cursiosity, mostly */
+int max_gain;
+int cb6, cb7; /* watch bits 6 and 7 of the control code, for curiosity */
 } hdcd_state_t;
 
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
+
+/* User information/stats */
+int hdcd_detected;
+int uses_peak_extend;
+int uses_transient_filter; /* detected, but not implemented */
+float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */
 } HDCDContext;
 
 static const AVOption hdcd_options[] = {
@@ -840,6 +859,8 @@ AVFILTER_DEFINE_CLASS(hdcd);
 
 static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 {
+int i;
+
 state->window = 0;
 state->readahead = 32;
 state->arg = 0;
@@ -853,6 +874,13 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->code_counterA = 0;
 state->code_counterB = 0;
 state->code_counterC = 0;
+
+state->count_peak_extend = 0;
+state->count_transient_filter = 0;
+for(i = 0; i < 16; i++) state->gain_counts[i] = 0;
+state->max_gain = 0;
+state->cb6 = 0;
+state->cb7 = 0;
 }
 
 static int integrate(hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride)
@@ -949,6 +977,7 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int gain, int
 int len = FFMIN(count, target_gain - gain);
 /* attenuate slowly */
 for (i = 0; i < len; i++) {
+++gain;
 APPLY_GAIN(*samples, gain);
 samples += stride;
 }
@@ -982,6 +1011,18 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int gain, int
 return gain;
 }
 
+/* update the user info/flags */
+static void hdcd_update_info(hdcd_state_t *state)
+{
+if (state->control & 16) state->count_peak_extend++;
+if (state->control & 32) state->count_transient_filter++;
+state->gain_counts[state->control &

[FFmpeg-devel] [PATCH] small fix in af_hdcd.c where gain was not bing adjusted for "attenuate slowly"

2016-07-04 Thread Burt P
Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 16bdcb0..92f3c9e 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -949,6 +949,7 @@ static int hdcd_envelope(int32_t *samples, int count, int 
stride, int gain, int
 int len = FFMIN(count, target_gain - gain);
 /* attenuate slowly */
 for (i = 0; i < len; i++) {
+++gain;
 APPLY_GAIN(*samples, gain);
 samples += stride;
 }
-- 
2.7.4

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

2016-07-03 Thread Burt P.
I've attached a third attempt at this patch with all the
suggestions by Carl Eugen Hoyos and Moritz Barsnick,
including converting the UPDATE_INFO macro into a
function, and some more comments and little fixes.

Thanks.
From 2dbbfc0cea83b769b5b02eecc5ec3dabc477457b Mon Sep 17 00:00:00 2001
From: Burt P <pbu...@gmail.com>
Date: Sun, 3 Jul 2016 21:46:10 -0500
Subject: [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

The new HDCD filter really does nothing to show that it is working or
that HDCD control information was even detected in the stream. This
patch collects information about the decode, like which features were
used, and reports it to the user at the end.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 65 +++
 1 file changed, 65 insertions(+)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 16bdcb0..d00d846 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -823,11 +823,27 @@ typedef struct {
 int code_counterA;
 int code_counterB;
 int code_counterC;
+
+/* For user information/stats, pulled up into HDCDContext
+ * by filter_frame() */
+int hdcd_detected; /* if ever detected */
+int peak_extend;   /* if ever enabled */
+int transient_filter;  /* if ever enabled */
+/* 4-bit (3.1) fixed-point, << 7 *
+ * stored positive, but values are negative, so
+ * min and max are swapped when converted to float later */
+int gain_min, gain_max;
 } hdcd_state_t;
 
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
+
+/* User information/stats */
+int hdcd_detected;
+int uses_peak_extend;
+int uses_transient_filter; /* detected, but not implemented */
+float gain_min, gain_max;
 } HDCDContext;
 
 static const AVOption hdcd_options[] = {
@@ -853,6 +869,12 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->code_counterA = 0;
 state->code_counterB = 0;
 state->code_counterC = 0;
+
+state->hdcd_detected = 0;
+state->peak_extend = 0;
+state->gain_min = 0;
+state->gain_max = 0;
+state->transient_filter = 0;
 }
 
 static int integrate(hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride)
@@ -982,6 +1004,20 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int gain, int
 return gain;
 }
 
+/* update the user info/flags */
+static void hdcd_update_info(hdcd_state_t *state)
+{
+int target_gain = (state->control & 15) << 7;
+state->gain_min = FFMIN(state->gain_min, target_gain);
+state->gain_max = FFMAX(state->gain_max, target_gain);
+state->peak_extend |= !!(state->control & 16);
+state->transient_filter |= !!(state->control & 32);
+state->hdcd_detected |= target_gain
+|| state->peak_extend
+|| state->transient_filter
+|| state->sustain;
+}
+
 static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int stride)
 {
 int32_t *samples_end = samples + count * stride;
@@ -990,6 +1026,8 @@ static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int s
 int target_gain = (state->control & 15) << 7;
 int lead = 0;
 
+hdcd_update_info(state);
+
 while (count > lead) {
 int envelope_run;
 int run;
@@ -1006,6 +1044,7 @@ static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int s
 lead = run - envelope_run;
 peak_extend = (state->control & 16);
 target_gain = (state->control & 15) << 7;
+hdcd_update_info(state);
 }
 if (lead > 0) {
 av_assert0(samples + lead * stride <= samples_end);
@@ -1015,6 +1054,9 @@ static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int s
 state->running_gain = gain;
 }
 
+/* convert to float from (4-bit (3.1) fixed-point, << 7) */
+#define GAINTOFLOAT(g) ((float)(g>>8) + ((g>>7 & 1) ? 0.5 : 0.0))
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
 AVFilterContext *ctx = inlink->dst;
@@ -1024,6 +1066,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 const int16_t *in_data;
 int32_t *out_data;
 int n, c;
+int gain_min = 0;
+int gain_max = 0;
 
 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
@@ -1042,8 +1086,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
 hdcd_process(state, out_data + c, in->nb_samples, out->channels);
+
+s->hdcd_detected |= state->hdcd_detected;
+s->uses_peak_extend |= state->peak_extend;
+s->uses_transient_filter |= state->transient_filter;
+   

Re: [FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

2016-07-03 Thread Burt P.
Thanks. I've sent a new version of the patch in reply to Carl Eugen
Hoyos, and using git send-email this time, but I saw this message and
included most of the things you mentioned.
I'm still getting used to this.

Anyway, I am curious why both of you think UPDATE_INFO should not
remain a macro? It is only used in that one function, but
unfortunately twice, so I thought a macro would do well there.



On Sun, Jul 3, 2016 at 6:34 AM, Moritz Barsnick <barsn...@gmx.net> wrote:
> On Sat, Jul 02, 2016 at 23:53:20 -0500, Burt P. wrote:
>
>>  static int integrate(hdcd_state_t *state, int *flag, const int32_t
>> *samples, int count, int stride)
>
> Your mailer is breaking likes in the patch. You may need to attach it
> as a text file, or actually use git send-email.
>
>> +/* update the user info/flags */
>> +#define UPDATE_INFO(s,pe,tg,tf) do{if (pe || tg || tf || s->sustain)
>> { s->_hdcd_detected = 1; } if (pe) { s->_peak_extend = 1; } if (tf) {
>> s->_transient_filter = 1;} if (tg < s->_gain_min) { s->_gain_min=tg; }
>>  if (tg > s->_gain_max) { s->_gain_max=tg; } }while(0);
>
> Not more readable, but more compact (and possibly more ffmpeg style):
> s->_hdcd_detected = pe || tg || tf || s->sustain;
> s->_peak_extend = !!pe;
> s->_transient_filter = !!tf;
> [...]
>
>> +#define GAINTOFLOAT(g) ((float)(g>>8) + ((float)(g>>7 & 1) * 0.5))
>
> I can think of other ways to do this, but as it's not performace
> relevant, it shouldn't matter.
>
>> +if (state->_gain_min < _gain_min) { _gain_min = state->_gain_min; }
>> +if (state->_gain_max > _gain_max) { _gain_max = state->_gain_max; }
>
> ffmpeg style would probably be:
> if (state->_gain_max > _gain_max)
> _gain_max = state->_gain_max;
>
> but for readability, I would have said:
> _gain_max = FFMIN(_gain_max, state->_gain_max);
> (Or does ffmpeg have an explicit macro for "limit this value"?).
>
> Same above in the UPDATE_INFO macro (-> function).
>
> Moritz
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

2016-07-03 Thread Burt P
The new HDCD filter really does nothing to show that it is working or
that HDCD control information was even detected in the stream. This
patch collects information about the decode, like which features were
used, and reports it to the user at the end.

Signed-off-by: Burt P <pbu...@gmail.com>
---
 libavfilter/af_hdcd.c | 61 +++
 1 file changed, 61 insertions(+)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 16bdcb0..c0233eb 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -823,11 +823,27 @@ typedef struct {
 int code_counterA;
 int code_counterB;
 int code_counterC;
+
+/* For user information/stats, pulled up into HDCDContext
+ * by filter_frame() */
+int hdcd_detected;
+int peak_extend;
+int transient_filter;
+/* 4-bit (3.1) fixed-point, << 7 *
+ * stored positive, but values are negative, so
+ * min and max are swapped when converted to float later */
+int gain_min, gain_max;
 } hdcd_state_t;
 
 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
+
+/* User information/stats */
+int hdcd_detected;
+int peak_extend;
+int transient_filter; /* detected, but not implemented */
+float gain_min, gain_max;
 } HDCDContext;
 
 static const AVOption hdcd_options[] = {
@@ -853,6 +869,12 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->code_counterA = 0;
 state->code_counterB = 0;
 state->code_counterC = 0;
+
+state->hdcd_detected = 0;
+state->peak_extend = 0;
+state->gain_min = 0;
+state->gain_max = 0;
+state->transient_filter = 0;
 }
 
 static int integrate(hdcd_state_t *state, int *flag, const int32_t *samples, 
int count, int stride)
@@ -982,14 +1004,25 @@ static int hdcd_envelope(int32_t *samples, int count, 
int stride, int gain, int
 return gain;
 }
 
+/* update the user info/flags */
+#define UPDATE_INFO(s,pe,tg,tf) do{ \
+if (pe || tg || tf || s->sustain) { s->hdcd_detected = 1; } \
+s->peak_extend = !!pe; \
+s->transient_filter = !!tf; \
+s->gain_min = FFMIN(s->gain_min, tg); \
+s->gain_max = FFMAX(s->gain_max, tg); }while(0);
+
 static void hdcd_process(hdcd_state_t *state, int32_t *samples, int count, int 
stride)
 {
 int32_t *samples_end = samples + count * stride;
 int gain = state->running_gain;
 int peak_extend = (state->control & 16);
 int target_gain = (state->control & 15) << 7;
+int transient_filter = state->control & 32;
 int lead = 0;
 
+UPDATE_INFO(state, peak_extend, target_gain, transient_filter);
+
 while (count > lead) {
 int envelope_run;
 int run;
@@ -1006,6 +1039,8 @@ static void hdcd_process(hdcd_state_t *state, int32_t 
*samples, int count, int s
 lead = run - envelope_run;
 peak_extend = (state->control & 16);
 target_gain = (state->control & 15) << 7;
+transient_filter = state->control & 32;
+UPDATE_INFO(state, peak_extend, target_gain, transient_filter);
 }
 if (lead > 0) {
 av_assert0(samples + lead * stride <= samples_end);
@@ -1015,6 +1050,9 @@ static void hdcd_process(hdcd_state_t *state, int32_t 
*samples, int count, int s
 state->running_gain = gain;
 }
 
+/* convert to float from (4-bit (3.1) fixed-point, << 7) */
+#define GAINTOFLOAT(g) ((float)(g>>8) + ((g>>7 & 1) ? 0.5 : 0.0))
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
 AVFilterContext *ctx = inlink->dst;
@@ -1024,6 +1062,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 const int16_t *in_data;
 int32_t *out_data;
 int n, c;
+int gain_min = 0;
+int gain_max = 0;
 
 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
@@ -1042,8 +1082,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*in)
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
 hdcd_process(state, out_data + c, in->nb_samples, out->channels);
+
+s->hdcd_detected |= state->hdcd_detected;
+s->peak_extend |= state->peak_extend;
+s->transient_filter |= state->transient_filter;
+gain_min = FFMIN(gain_min, state->gain_min);
+gain_max = FFMAX(gain_max, state->gain_max);
 }
 
+/* swapped here because the fixed-point always-negative values
+ *  are stored positive */
+s->gain_max = -(GAINTOFLOAT(gain_min)); /* max = -min */
+s->gain_min = -(GAINTOFLOAT(gain_max)); /* min = -max */
+
 av_frame_free();
 return ff_filter_frame(outlink, out);
 }
@@ -1104,6 +1155,13 @@ static av_cold void uninit(AVFilterContext *ctx)
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: counter A: %d, B: %d, C: 
%d\n", i

[FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report

2016-07-02 Thread Burt P.
The new HDCD filter really does nothing to show that it is working or
that HDCD control
information was even detected in the stream. This patch collects
information about the
decode, like which features were used, and reports it to the user at the end.
First patch I've ever tried to submit to ffmpeg. Has a couple long lines.

Signed-off-by: bp0 
---
 libavfilter/af_hdcd.c | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 16bdcb0..f298765 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -823,11 +823,25 @@ typedef struct {
 int code_counterA;
 int code_counterB;
 int code_counterC;
+
+/* For user information/stats, pulled up into HDCDContext
+ * by filter_frame() */
+int _hdcd_detected;
+int _peak_extend;
+int _gain_min; /* 4-bit (3.1) fixed-point, << 7 */
+int _gain_max; /* 4-bit (3.1) fixed-point, << 7 */
+int _transient_filter;
 } hdcd_state_t;

 typedef struct HDCDContext {
 const AVClass *class;
 hdcd_state_t state[2];
+
+/* User information/stats */
+int hdcd_detected;
+int peak_extend;
+int transient_filter; /* detected, but not implemented */
+float gain_min, gain_max; /* stored positive, but values are negative */
 } HDCDContext;

 static const AVOption hdcd_options[] = {
@@ -853,6 +867,12 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate)
 state->code_counterA = 0;
 state->code_counterB = 0;
 state->code_counterC = 0;
+
+state->_hdcd_detected = 0;
+state->_peak_extend = 0;
+state->_gain_min = 0;
+state->_gain_max = 0;
+state->_transient_filter = 0;
 }

 static int integrate(hdcd_state_t *state, int *flag, const int32_t
*samples, int count, int stride)
@@ -982,14 +1002,20 @@ static int hdcd_envelope(int32_t *samples, int
count, int stride, int gain, int
 return gain;
 }

+/* update the user info/flags */
+#define UPDATE_INFO(s,pe,tg,tf) do{if (pe || tg || tf || s->sustain)
{ s->_hdcd_detected = 1; } if (pe) { s->_peak_extend = 1; } if (tf) {
s->_transient_filter = 1;} if (tg < s->_gain_min) { s->_gain_min=tg; }
 if (tg > s->_gain_max) { s->_gain_max=tg; } }while(0);
+
 static void hdcd_process(hdcd_state_t *state, int32_t *samples, int
count, int stride)
 {
 int32_t *samples_end = samples + count * stride;
 int gain = state->running_gain;
 int peak_extend = (state->control & 16);
 int target_gain = (state->control & 15) << 7;
+int transient_filter = (state->control & 32);
 int lead = 0;

+UPDATE_INFO(state, peak_extend, target_gain, transient_filter);
+
 while (count > lead) {
 int envelope_run;
 int run;
@@ -1006,6 +1032,8 @@ static void hdcd_process(hdcd_state_t *state,
int32_t *samples, int count, int s
 lead = run - envelope_run;
 peak_extend = (state->control & 16);
 target_gain = (state->control & 15) << 7;
+transient_filter = (state->control & 32);
+UPDATE_INFO(state, peak_extend, target_gain, transient_filter);
 }
 if (lead > 0) {
 av_assert0(samples + lead * stride <= samples_end);
@@ -1015,6 +1043,9 @@ static void hdcd_process(hdcd_state_t *state,
int32_t *samples, int count, int s
 state->running_gain = gain;
 }

+/* convert to float from (4-bit (3.1) fixed-point, << 7) */
+#define GAINTOFLOAT(g) ((float)(g>>8) + ((float)(g>>7 & 1) * 0.5))
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
 AVFilterContext *ctx = inlink->dst;
@@ -1024,6 +1055,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 const int16_t *in_data;
 int32_t *out_data;
 int n, c;
+int _gain_min = 0;
+int _gain_max = 0;

 out = ff_get_audio_buffer(outlink, in->nb_samples);
 if (!out) {
@@ -1042,8 +1075,17 @@ static int filter_frame(AVFilterLink *inlink,
AVFrame *in)
 for (c = 0; c < inlink->channels; c++) {
 hdcd_state_t *state = >state[c];
 hdcd_process(state, out_data + c, in->nb_samples, out->channels);
+
+s->hdcd_detected |= state->_hdcd_detected;
+s->peak_extend |= state->_peak_extend;
+s->transient_filter |= state->_transient_filter;
+if (state->_gain_min < _gain_min) { _gain_min = state->_gain_min; }
+if (state->_gain_max > _gain_max) { _gain_max = state->_gain_max; }
 }

+s->gain_min = GAINTOFLOAT(_gain_min);
+s->gain_max = GAINTOFLOAT(_gain_max);
+
 av_frame_free();
 return ff_filter_frame(outlink, out);
 }
@@ -1104,6 +1146,12 @@ static av_cold void uninit(AVFilterContext *ctx)
 av_log(ctx, AV_LOG_VERBOSE, "Channel %d: counter A: %d, B:
%d, C: %d\n", i, state->code_counterA,
 state->code_counterB, state->code_counterC);
 }
+
+av_log(ctx, AV_LOG_INFO, "HDCD detected: %s, peak_extend: %s,
transient_filter: %s, min_gain: -%0.1f dB, max_gain: -%0.1f dB\n",
+