[FFmpeg-devel] [PATCH] af_hdcd: more FATE tests
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 --- 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_SAMPLES-$(call
Re: [FFmpeg-devel] [PATCH] af_hdcd: more FATE tests
On Sun, Dec 18, 2016 at 3:30 AM, Hendrik Leppkes wrote: > On Sun, Dec 18, 2016 at 8:42 AM, 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 >> 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] [PATCHv2] af_hdcd: more FATE tests
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 --- 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
[FFmpeg-devel] [PATCHv3] af_hdcd: more FATE tests
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 --- 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-filter-hdcd-analyze
Re: [FFmpeg-devel] [PATCHv3] af_hdcd: more FATE tests
On Sun, Dec 18, 2016 at 6:54 PM, Michael Niedermayer 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
Re: [FFmpeg-devel] [PATCHv3] af_hdcd: more FATE tests
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
[FFmpeg-devel] [PATCHv4] af_hdcd: more FATE tests
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 --- 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-ltgm: REF = 76ffd86b762b5a93332039
Re: [FFmpeg-devel] [PATCHv4] af_hdcd: more FATE tests
applied. -- Burt ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/5] af_hdcd changes
Hi. Patches follow. -- Burt ___ 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
* use the actual sample rate * use a more sensible frequency for the tone * update fate test result Signed-off-by: Burt P --- 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 4/5] af_hdcd: move decoding setup from init to config_input
Signed-off-by: Burt P --- 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(&s->detect); -for (c = 0; c < HDCD_MAX_CHANNELS; c++) { -hdcd_reset(&s->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(&s->detect); +for (c = 0; c < HDCD_MAX_CHANNELS; c++) { +hdcd_reset(&s->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 1/5] af_hdcd: some types renamed to remove _t
Following a suggestion by Diego Biurrun. _t is reserved for POSIX, apparently. Signed-off-by: Burt P --- 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 +1213,7 @@ static int
[FFmpeg-devel] [PATCH 3/5] af_hdcd: fix possible integer overflow
Signed-off-by: Burt P --- 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(&s->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 2/5] af_hdcd: hdcd_analyze_gen() using int instead of float
Signed-off-by: Burt P --- 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 cde2340..c8bda82 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -1316,11 +1316,10 @@ static void hdcd_analyze_prepare(hdcd_state *state, int32_t *samples, int count, /** encode a value in the given sample by adjusting the amplitude */ static int32_t hdcd_analyze_gen(int32_t sample, unsigned int v, unsigned int maxv) { -float sflt = sample, vv = v; -vv /= maxv; -if (vv > 1.0) vv = 1.0; -sflt *= 1.0 + (vv * 18); -return (int32_t)sflt; +static const int r = 18, m = 1024; +int64_t s64 = sample; +v = m + (v * r * m / maxv); +return (int32_t)(s64 * v / m); } /** behaves like hdcd_envelope(), but encodes processing information in -- 2.7.4 ___ 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
On Tue, Sep 6, 2016 at 5:22 AM, Carl Eugen Hoyos wrote: > 2016-09-05 13:18 GMT+02:00 Burt P : >> * 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
Re: [FFmpeg-devel] [PATCH 5/5] af_hdcd: tweak hdcd_analyze_prepare() a bit
On Tue, Sep 6, 2016 at 6:12 AM, Carl Eugen Hoyos wrote: > 2016-09-06 13:02 GMT+02:00 Burt P. : >> On Tue, Sep 6, 2016 at 5:22 AM, Carl Eugen Hoyos wrote: >>> 2016-09-05 13:18 GMT+02:00 Burt P : >>>> * 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
applied On Mon, Sep 5, 2016 at 6:18 AM, Burt P wrote: > * use the actual sample rate > * use a more sensible frequency for the tone > * update fate test result > > Signed-off-by: Burt P > --- > 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 4/5] af_hdcd: move decoding setup from init to config_input
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
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 wrote: > On Mon, Sep 05, 2016 at 06:18:43AM -0500, Burt P wrote: >> Signed-off-by: Burt P >> --- >> 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 1/5] af_hdcd: some types renamed to remove _t
applied -- Burt ___ 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
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
[FFmpeg-devel] [PATCH 1/5] af_hdcd: allow all HDCD sample rates
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 --- 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(&sample_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
[FFmpeg-devel] [PATCH 3/5] af_hdcd: add mono as a supported channel layout
Signed-off-by: Burt P --- 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(&layouts, AV_CH_LAYOUT_MONO); +if (ret < 0) +return ret; ret = ff_add_channel_layout(&layouts, 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 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/5] af_hdcd: hdcd_scan() and hdcd_integrate() handle stereo and single channel
New versions of hdcd_scan() and hdcd_integrate() that also do the work of hdcd_scan_stereo() and hdcd_integrate_stereo(). Some code split into previously separate functions to remove duplication is now merged back into each function in the single place where it is used. Signed-off-by: Burt P --- libavfilter/af_hdcd.c | 303 ++ 1 file changed, 85 insertions(+), 218 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 6f35c09..b5aad85 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -1031,267 +1031,134 @@ static void hdcd_reset(hdcd_state *state, unsigned rate, unsigned cdt_ms) state->_ana_snb = 0; } -/** update the user info/counters */ -static void hdcd_update_info(hdcd_state *state) +static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, int *flag, const int32_t *samples, int count, int stride) { -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)); -} - -typedef enum { -HDCD_CODE_NONE=0, -HDCD_CODE_A, -HDCD_CODE_A_ALMOST, -HDCD_CODE_B, -HDCD_CODE_B_CHECKFAIL, -HDCD_CODE_EXPECT_A, -HDCD_CODE_EXPECT_B, -} hdcd_code_result; - -static hdcd_code_result hdcd_code(const uint32_t bits, unsigned char *code) -{ -if ((bits & 0x0fa00500) == 0x0fa00500) { -/* A: 8-bit code 0x7e0fa005[..] */ -if ((bits & 0xc8) == 0) { -/* [..pt ] - * 0x0fa005[..] -> 0b[00.. 0...], gain part doubled */ -*code = (bits & 255) + (bits & 7); -return HDCD_CODE_A; -} else -return HDCD_CODE_A_ALMOST; /* one of bits 3, 6, or 7 was not 0 */ -} else if ((bits & 0xa006) == 0xa006) { -/* B: 8-bit code, 8-bit XOR check, 0x7e0fa006[] */ -if (((bits ^ (~bits >> 8 & 255)) & 0x00ff) == 0xa006) { -/* check: [..pt ~(..pt )] - * 0xa006[] -> 0b[ ] */ -*code = bits >> 8 & 255; -return HDCD_CODE_B; -} else -return HDCD_CODE_B_CHECKFAIL; /* XOR check failed */ -} -if (bits == 0x7e0fa005) -return HDCD_CODE_EXPECT_A; -else if (bits == 0x7e0fa006) -return HDCD_CODE_EXPECT_B; - -return HDCD_CODE_NONE; -} - -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); -int i; +uint32_t bits[HDCD_MAX_CHANNELS]; +int result = count; +int i, j, f; *flag = 0; -for (i = result - 1; i >= 0; i--) { -bits |= (*samples & 1) << i; /* might be better as a conditional? */ -samples += stride; -} +memset(bits, 0, sizeof(bits)); +if (stride < channels) stride = channels; -state->window = (state->window << result) | bits; -state->readahead -= result; -if (state->readahead > 0) -return result; +for (i = 0; i < channels; i++) +result = FFMIN(states[i].readahead, result); -bits = (state->window ^ state->window >> 5 ^ state->window >> 23); - -if (state->arg) { -switch (hdcd_code(bits, &state->control)) { -case HDCD_CODE_A: -*flag = 1; -state->code_counterA++; -break; -case HDCD_CODE_B: -*flag = 1; -state->code_counterB++; -break; -case HDCD_CODE_A_ALMOST: -state->code_counterA_almost++; -av_log(ctx->fctx, AV_LOG_VERBOSE, -"hdcd error: Control A almost: 0x%02x near %d\n", bits & 0xff, ctx->sample_count); -break; -case HDCD_CODE_B_CHECKFAIL: -state->code_counterB_checkfails++; -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); -break; -case HDCD_CODE_NONE: -state->code_counterC_unmatched++; -av_log(ctx->fctx, AV_LOG_VERBOSE, -"hdcd error: Unmatched code: 0x%08x near %d\n", bits, ctx->sample_count); -default: -av_log(ctx->fctx, AV_LOG_INFO, -"hdcd error: Unexpected return value from hdcd_code()\n"); -av_assert0(0); /* die
[FFmpeg-devel] Alternate HDCD format/rate support
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 2/5] af_hdcd: support s16p (WavPack) directly
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 --- 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(&s->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] [PATCH 5/5] af_hdcd: add experimental 20 and 24-bit decoding support
As in this libhdcd commit: [0] I don't have any legitimate 20 or 24-bit HDCD to test. It is known that the PM Model Two would insert packets into 20 and 24-bit output, but I have no idea what differences in behavior existed when decoding 20 or 24-bit. For now, as with 16-bit, PE (if enabled) will expand the top 3dB into 9dB and LLE (gain adjust) will be applied if signaled. Also, As all known valid HDCD sample formats and sample rates are now handled by the filter, remove the scan that "invades the privacy" of the filter graph and turn off autoconvert by default as requested by Nicolas George. [1] [0] https://github.com/bp0/libhdcd/commit/dc32b383efab5608820af4f641db292f9a776778 [1] http://ffmpeg.org/pipermail/ffmpeg-devel/2016-August/197571.html Signed-off-by: Burt P --- libavfilter/af_hdcd.c | 135 ++ 1 file changed, 69 insertions(+), 66 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index b5aad85..91f84ae 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -964,6 +964,8 @@ typedef struct HDCDContext { int cdt_ms; /**< code detect timer period in ms */ int disable_autoconvert; /**< disable any format conversion or resampling in the filter graph */ + +int bits_per_sample; /**< bits per sample 16, 20, or 24 */ /* end AVOption members */ /** config_input() and config_output() scan links for any resampling @@ -983,7 +985,7 @@ typedef struct HDCDContext { #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption hdcd_options[] = { { "disable_autoconvert", "Disable any format conversion or resampling in the filter graph.", -OFFSET(disable_autoconvert), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A }, +OFFSET(disable_autoconvert), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A }, { "process_stereo", "Process stereo channels together. Only apply target_gain when both channels match.", OFFSET(process_stereo), AV_OPT_TYPE_BOOL, { .i64 = HDCD_PROCESS_STEREO_DEFAULT }, 0, 1, A }, { "cdt_ms", "Code detect timer period in ms.", @@ -997,6 +999,11 @@ static const AVOption hdcd_options[] = { { "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" }, +{ "bits_per_sample", "Valid bits per sample (location of the true LSB).", +OFFSET(bits_per_sample), AV_OPT_TYPE_INT, { .i64=16 }, 16, 24, A, "bits_per_sample"}, +{ "16", "16-bit (in s32 or s16)", 0, AV_OPT_TYPE_CONST, {.i64=16}, 0, 0, A, "bits_per_sample" }, +{ "20", "20-bit (in s32)", 0, AV_OPT_TYPE_CONST, {.i64=20}, 0, 0, A, "bits_per_sample" }, +{ "24", "24-bit (in s32)", 0, AV_OPT_TYPE_CONST, {.i64=24}, 0, 0, A, "bits_per_sample" }, {NULL} }; @@ -1253,29 +1260,34 @@ static int hdcd_analyze(int32_t *samples, int count, int stride, int gain, int t } /** apply HDCD decoding parameters to a series of samples */ -static int hdcd_envelope(int32_t *samples, int count, int stride, int gain, int target_gain, int extend) +static int hdcd_envelope(int32_t *samples, int count, int stride, int vbits, int gain, int target_gain, int extend) { static const int max_asample = sizeof(peaktab) / sizeof(peaktab[0]) - 1; int32_t *samples_end = samples + stride * count; int i; +int pe_level = PEAK_EXT_LEVEL, shft = 15; +if (vbits != 16) { +pe_level = (1 << (vbits - 1)) - (0x8000 - PEAK_EXT_LEVEL); +shft = 32 - vbits - 1; +} av_assert0(PEAK_EXT_LEVEL + max_asample == 0x8000); if (extend) { for (i = 0; i < count; i++) { int32_t sample = samples[i * stride]; -int32_t asample = abs(sample) - PEAK_EXT_LEVEL; +int32_t asample = abs(sample) - pe_level; if (asample >= 0) { av_assert0(asample <= max_asample); sample = sample >= 0 ? peaktab[asample] : -peaktab[asample]; } else -sample <<= 15; +sample <<= shft; samples[i * stride] = sample; } } else { for (i = 0; i < count; i++) -samples[i * stride] <<= 15; +samples[i * stride] <<= shft; } if (gain <= target_gain) { @@ -1370,7 +1382,7 @@ static void hdcd_process(HDCDContext *ctx, hdcd_state *state, int32_t *samples, if (ctx->analyze_mode)
Re: [FFmpeg-devel] [PATCH 1/5] af_hdcd: allow all HDCD sample rates
applied -- 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
applied -- Burt ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/5] af_hdcd: support s16p (WavPack) directly
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: add mono as a supported channel layout
applied -- Burt On Sun, Oct 2, 2016 at 2:46 AM, Burt P wrote: > Signed-off-by: Burt P > --- > 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(&layouts, AV_CH_LAYOUT_MONO); > +if (ret < 0) > +return ret; > ret = ff_add_channel_layout(&layouts, 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 5/5] af_hdcd: add experimental 20 and 24-bit decoding support
applied split into two commits -- Burt ___ 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
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 = &s->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(&in); 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", +(s->hdcd_detected) ? "yes" : "no",
[FFmpeg-devel] [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 --- 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 = &s->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(&in); 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, state-
Re: [FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report
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 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
Re: [FFmpeg-devel] [PATCH] libavfilter/af_hdcd.c: Collect HDCD stats and report
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 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 --- 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 = &s->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; +gain_min = FFMIN(gain_min, state
[FFmpeg-devel] [PATCH] small fix in af_hdcd.c where gain was not bing adjusted for "attenuate slowly"
Signed-off-by: Burt P --- 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
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 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 --- 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 & 15]++; +state->max_gain = FFMAX
[FFmpeg-devel] [PATCH] af_hdcd.c: only hdcd_update_info() when something changes, add error detection
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 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 --- 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) { +
[FFmpeg-devel] [PATCH 1/5] af_hdcd: integrate() renamed hdcd_integrate() to be consistent with the other function names
Signed-off-by: Burt P --- 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 89012eb..73a0b93 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -883,7 +883,7 @@ static void hdcd_reset(hdcd_state_t *state, unsigned rate) state->cb7 = 0; } -static int integrate(hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride) +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); @@ -941,7 +941,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 = integrate(state, &flag, samples, max - result, stride); +int consumed = hdcd_integrate(state, &flag, samples, max - result, stride); result += consumed; if (flag > 0) { state->sustain = state->sustain_reset; -- 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
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 4/5] af_hdcd: don't log full HDCD stats if HDCD was not detected
Signed-off-by: Burt P --- 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 5/5] af_hdcd: detect and report encoding errors and oddities
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 --- 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 = &s->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 =
[FFmpeg-devel] [PATCH 3/5] af_hdcd: only hdcd_update_info() when something changes
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 --- 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 = &s->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 2/5] af_hdcd: fewer false positives by ignoring code_counterC in HDCD detection
Signed-off-by: Burt P --- 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(&in); -- 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
Signed-off-by: Burt P --- 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] af_hdcd: Improve HDCD detection
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 --- 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 = &s->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(&in); return ff_filter_frame(outlink, out); -- 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
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 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 2/4] af_hdcd: more comments in state struct
Add some comments describing the fields in hdcd_state_t. Signed-off-by: Burt P --- 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
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
[FFmpeg-devel] [PATCH 1/4] af_hdcd: Improve HDCD detection
HDCD is now only considered detected if a valid packet is active in both channels simultaneously. Signed-off-by: Burt P --- 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 = &s->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(&in); 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 3/4] af_hdcd: Add counter for cdt expirations
Adds a counter for when the code detect timer expired without finding a valid packet. Signed-off-by: Burt P --- 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, &flag, 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 = &s->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
Re: [FFmpeg-devel] [PATCH] af_hdcd: Improve HDCD detection
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 4/4] af_hdcd: Report PE as being intermittent or permanent
The Peak Extend feature could be enabled permanently or only when needed. This is now reported. Signed-off-by: Burt P --- 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 = &s->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
[FFmpeg-devel] [PATCH] af_hdcd: Add counter for cdt expirations
Adds a counter for when the "code detect timer" expired without finding a valid packet. Signed-off-by: Burt P --- 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, &flag, 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 = &s->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 0/1] af_hdcd: Process stereo channels together, fix #5727
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: Process stereo channels together, fix #5727
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 --- 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 */ int hdcd_detec
Re: [FFmpeg-devel] [PATCH 0/1] af_hdcd: Process stereo channels together, fix #5727
> 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 0/7] fix(v2) for #5727 split up, plus other things
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
[FFmpeg-devel] [PATCH 5/7] af_hdcd: Move code detect/check into own function
Signed-off-by: Burt P --- libavfilter/af_hdcd.c | 86 +++ 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index aeb65eb..902827e 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -933,6 +933,45 @@ static void hdcd_update_info(hdcd_state_t *state) state->max_gain = FFMAX(state->max_gain, (state->control & 15)); } +typedef enum { +HDCD_CODE_NONE=0, +HDCD_CODE_A, +HDCD_CODE_A_ALMOST, +HDCD_CODE_B, +HDCD_CODE_B_CHECKFAIL, +HDCD_CODE_EXPECT_A, +HDCD_CODE_EXPECT_B, +} hdcd_code_result_t; + +static hdcd_code_result_t hdcd_code(const uint32_t bits, unsigned char *code) +{ +if ((bits & 0x0fa00500) == 0x0fa00500) { +/* A: 8-bit code 0x7e0fa005[..] */ +if ((bits & 0xc8) == 0) { +/* [..pt ] + * 0x0fa005[..] -> 0b[00.. 0...], gain part doubled */ +*code = (bits & 255) + (bits & 7); +return HDCD_CODE_A; +} else +return HDCD_CODE_A_ALMOST; /* one of bits 3, 6, or 7 was not 0 */ +} else if ((bits & 0xa006) == 0xa006) { +/* B: 8-bit code, 8-bit XOR check, 0x7e0fa006[] */ +if (((bits ^ (~bits >> 8 & 255)) & 0x00ff) == 0xa006) { +/* check: [..pt ~(..pt )] + * 0xa006[] -> 0b[ ] */ +*code = bits >> 8 & 255; +return HDCD_CODE_B; +} else +return HDCD_CODE_B_CHECKFAIL; /* XOR check failed */ +} +if (bits == 0x7e0fa005) +return HDCD_CODE_EXPECT_A; +else if (bits == 0x7e0fa006) +return HDCD_CODE_EXPECT_B; + +return HDCD_CODE_NONE; +} + static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride) { uint32_t bits = 0; @@ -953,44 +992,39 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t *state, int *flag, cons bits = (state->window ^ state->window >> 5 ^ state->window >> 23); if (state->arg) { -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); +switch (hdcd_code(bits, &state->control)) { +case HDCD_CODE_A: *flag = 1; state->code_counterA++; -} else { -/* one of bits 3, 6, or 7 was not 0 */ +break; +case HDCD_CODE_B: +*flag = 1; +state->code_counterB++; +break; +case HDCD_CODE_A_ALMOST: state->code_counterA_almost++; 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 */ -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 */ +break; +case HDCD_CODE_B_CHECKFAIL: state->code_counterB_checkfails++; 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(ctx->fctx, AV_LOG_VERBOSE, - "hdcd error: Unmatched code: 0x%08x near %d\n", bits, ctx->sample_count); +"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); +break; +case HDCD_CODE_NONE: +state->code_counterC_unmatched++; +av_log(ctx->fctx, AV_LOG_VERBOSE, +"hdcd error: Unmatched code: 0x%08x near %d\n", bits, ctx->sample_count); +default: +av_log(ctx->fctx, A
[FFmpeg-devel] [PATCH 6/7] af_hdcd: Process stereo channels together, fix #5727
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 --- 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, &ctx->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 1/7] af_hdcd: fix a minor annoyance
Signed-off-by: Burt P --- 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 2/7] af_hdcd: give cdt expired counter a value for never set
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 --- 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 3/7] af_hdcd: Improve error detection logging
* 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 --- 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, &flag, samples, max - result, stride); +int consumed = hdcd_integrate(ctx, state, &flag, 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 +
[FFmpeg-devel] [PATCH 7/7] af_hdcd: Warn if there is any resampling or format conversion in the link chain
HDCD is only encoded in s16@44100Hz. Scan the chain of AVFilterLinks for any resampling or format conversion/truncation that might cause problems for the filter and issue warnings. Signed-off-by: Burt P --- libavfilter/af_hdcd.c | 62 +++ 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index d46c7bc..2d7fe8d 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -885,6 +885,11 @@ typedef struct HDCDContext { * default is off */ int force_pe; +/* config_input() and config_output() scan links for any resampling + * or format changes. If found, warnings are issued and bad_config + * is set. */ +int bad_config; + 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 */ @@ -1519,25 +1524,29 @@ static av_cold void uninit(AVFilterContext *ctx) /* log the HDCD decode information */ 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", +"HDCD detected: yes, peak_extend: %s, max_gain_adj: %0.1f dB, transient_filter: %s, detectable errors: %d%s%s\n", 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)" : "" +s->det_errors, (s->det_errors) ? " (try -v verbose)" : "", +(s->bad_config) ? " (bad_config)" : "" ); else -av_log(ctx, AV_LOG_INFO, "HDCD detected: no\n"); +av_log(ctx, AV_LOG_INFO, "HDCD detected: no%s\n", +(s->bad_config) ? " (bad_config)" : "" +); } + static av_cold int init(AVFilterContext *ctx) { - HDCDContext *s = ctx->priv; int c; s->max_gain_adjustment = 0.0; s->sample_count = 0; s->fctx = ctx; +s->bad_config = 0; for (c = 0; c < HDCD_MAX_CHANNELS; c++) { hdcd_reset(&s->state[c], 44100); @@ -1551,19 +1560,64 @@ static av_cold int init(AVFilterContext *ctx) return 0; } +static int config_input(AVFilterLink *inlink) { +AVFilterContext *ctx = inlink->dst; +HDCDContext *s = ctx->priv; +AVFilterLink *lk = inlink; +while(lk != NULL) { +AVFilterContext *nextf = lk->src; +if (lk->format != AV_SAMPLE_FMT_S16 || 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 : "" +); +s->bad_config = 1; +break; +} +lk = (nextf->inputs) ? nextf->inputs[0] : NULL; +} +/* more warning will appear after config_output() */ +return 0; +} + static const AVFilterPad avfilter_af_hdcd_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .filter_frame = filter_frame, +.config_props = config_input, }, { NULL } }; +static int config_output(AVFilterLink *outlink) { +static const char hdcd_baduse[] = +"The HDCD filter is unlikely to produce a desirable result in this context."; +AVFilterContext *ctx = outlink->src; +HDCDContext *s = ctx->priv; +AVFilterLink *lk = outlink; +while(lk != NULL) { +AVFilterContext *nextf = lk->dst; +if (lk->format == AV_SAMPLE_FMT_S16 || lk->format == AV_SAMPLE_FMT_U8) { +av_log(ctx, AV_LOG_WARNING, "s24 output is being truncated to %s at %s. (Try -f s24le after the filter)\n", +av_get_sample_fmt_name(lk->format), +(nextf->name) ? nextf->name : "" +); +s->bad_config = 1; +break; +} +lk = (nextf->outputs) ? nextf->outputs[0] : NULL; +} +if (s->bad_config) +av_log(ctx, AV_LOG_WARNING, "%s\n", hdcd_baduse); +return 0; +} + static const AVFilterPad avfilter_af_hdcd_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, +.config_props = config_output, }, { NULL } }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/7] af_hdcd: add force_pe filter option
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 --- 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, &peak_extend, &target_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, &peak_extend, &target_gain); } if (lead > 0) { av_assert0(samples + lead * stride <= samples_end); @@ -1283,6 +1298,9 @@ static av_cold int init(AVFilterContext *ctx) hdcd_reset(&s->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] MAINTAINERS: Add myself for af_hdcd
Signed-off-by: Burt P --- 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] af_hdcd: add flags to AVOption defs
Signed-off-by: Burt P --- 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] af_hdcd: add flags to AVOption defs
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] [PATCHv2] af_hdcd: Process stereo channels together, fix #5727
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 --- 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, &ctx->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, +
Re: [FFmpeg-devel] FFmpeg 3.1.2
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] [PATCH 0/2] Analyze mode
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
[FFmpeg-devel] [PATCH 2/2] af_hdcd: Add analyze mode
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 --- 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 *ctx, const int3
[FFmpeg-devel] [PATCH 1/2] af_hdcd: convert AVOptions from INT to BOOL
As suggested by Timothy Gu. Signed-off-by: Burt P --- 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] [PATCHv2] af_hdcd: Add analyze mode
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 --- 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 *ctx, const int3
[FFmpeg-devel] [PATCHv3] af_hdcd: Add analyze mode (v3)
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 --- 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 *ctx, const int3
Re: [FFmpeg-devel] [PATCH 1/2] af_hdcd: convert AVOptions from INT to BOOL
applied thx :) On Fri, Aug 5, 2016 at 4:54 PM, Burt P wrote: > As suggested by Timothy Gu. > > Signed-off-by: Burt P > --- > 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
Re: [FFmpeg-devel] [PATCH 2/2] aacenc: unmark the fast coder as experimental
"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 = &ff_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
[FFmpeg-devel] [PATCHv4] af_hdcd: Add analyze mode (v4)
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 --- 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 adjusting the amplitu
[FFmpeg-devel] [PATCHv5] af_hdcd: Add analyze mode
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 --- 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 adjusting the amplitu
[FFmpeg-devel] [PATCH] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P
Signed-off-by: Burt P --- 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] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P
Signed-off-by: Burt P --- 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
Re: [FFmpeg-devel] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P
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
Re: [FFmpeg-devel] [PATCHv2] af_hdcd: Don't warn if converting from AV_SAMPLE_FMT_S16P
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] [PATCHv5] af_hdcd: Add analyze mode
applied On Sun, Aug 7, 2016 at 2:50 AM, Burt P 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 > --- > 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
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 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
[FFmpeg-devel] avfilter_graph_set_auto_convert() appears to do nothing
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&q=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
[FFmpeg-devel] [PATCHv2] avfiltergraph.c: restore disabling of auto conversions
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 --- 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] [PATCH] avfiltergraph.c: restore disabling of auto conversions
Signed-off-by: Burt P --- 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
Re: [FFmpeg-devel] avfilter_graph_set_auto_convert() appears to do nothing
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
Re: [FFmpeg-devel] [PATCHv2] avfiltergraph.c: restore disabling of auto conversions
applied On Wed, Aug 10, 2016 at 4:09 AM, Burt P 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 > --- > 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
[FFmpeg-devel] [PATCH] af_volumedetect: Work with sample formats other than s16/s16p
The histogram will still only be shown for s16 and s16p. Signed-off-by: Burt P --- libavfilter/af_volumedetect.c | 133 ++ 1 file changed, 121 insertions(+), 12 deletions(-) diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c index 4815bcc..3ee664f 100644 --- a/libavfilter/af_volumedetect.c +++ b/libavfilter/af_volumedetect.c @@ -24,6 +24,8 @@ #include "avfilter.h" #include "internal.h" +#define USE_OLD_VERSION 0 /* 0 or 1 */ + typedef struct { /** * Number of samples at each PCM value. @@ -31,18 +33,38 @@ typedef struct { * The extra element is there for symmetry. */ uint64_t histogram[0x10001]; +int use_hist; +int sformat; +double peak; +double power; +uint64_t nb_samples; } VolDetectContext; static int query_formats(AVFilterContext *ctx) { -static const enum AVSampleFormat sample_fmts[] = { -AV_SAMPLE_FMT_S16, -AV_SAMPLE_FMT_S16P, -AV_SAMPLE_FMT_NONE +static const enum AVSampleFormat sample_fmts[][11] = { +{ /* [0]: USE_OLD_VERSION = 0 */ +AV_SAMPLE_FMT_S16, +AV_SAMPLE_FMT_S16P, +AV_SAMPLE_FMT_U8, +AV_SAMPLE_FMT_U8P, +AV_SAMPLE_FMT_S32, +AV_SAMPLE_FMT_S32P, +AV_SAMPLE_FMT_FLT, +AV_SAMPLE_FMT_FLTP, +AV_SAMPLE_FMT_DBL, +AV_SAMPLE_FMT_DBLP, +AV_SAMPLE_FMT_NONE +}, +{ /* [1]: USE_OLD_VERSION = 1 */ +AV_SAMPLE_FMT_S16, +AV_SAMPLE_FMT_S16P, +AV_SAMPLE_FMT_NONE +}, }; AVFilterFormats *formats; -if (!(formats = ff_make_format_list(sample_fmts))) +if (!(formats = ff_make_format_list(sample_fmts[USE_OLD_VERSION]))) return AVERROR(ENOMEM); return ff_set_common_formats(ctx, formats); } @@ -56,22 +78,70 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *samples) int nb_channels = av_get_channel_layout_nb_channels(layout); int nb_planes = nb_channels; int plane, i; -int16_t *pcm; +uint8_t *pcm; +int sample_size; +double sample; + +vd->sformat = inlink->format; if (!av_sample_fmt_is_planar(samples->format)) { nb_samples *= nb_channels; nb_planes = 1; } for (plane = 0; plane < nb_planes; plane++) { -pcm = (int16_t *)samples->extended_data[plane]; -for (i = 0; i < nb_samples; i++) -vd->histogram[pcm[i] + 0x8000]++; +pcm = samples->extended_data[plane]; +sample_size = 0; +for (i = 0; i < nb_samples; i++) { +switch (inlink->format) { +case AV_SAMPLE_FMT_S16: +case AV_SAMPLE_FMT_S16P: +vd->histogram[*(int16_t*)pcm + 0x8000]++; +vd->use_hist = 1; +sample_size = sizeof(int16_t); +sample = (double)*(int16_t*)pcm; +sample /= 0x8000; +case AV_SAMPLE_FMT_U8: +case AV_SAMPLE_FMT_U8P: +if (!sample_size) { +sample_size = sizeof(uint8_t); +sample = (double)(*pcm); +sample -= 0x80; +sample /= 0x80; +} +case AV_SAMPLE_FMT_S32: +case AV_SAMPLE_FMT_S32P: +if (!sample_size) { +sample_size = sizeof(int32_t); +sample = (double)*(int32_t*)pcm; +sample /= 0x8000U; +} +case AV_SAMPLE_FMT_FLT: +case AV_SAMPLE_FMT_FLTP: +if (!sample_size) { +sample_size = sizeof(float); +sample = (double)*(float*)pcm; +} +case AV_SAMPLE_FMT_DBL: +case AV_SAMPLE_FMT_DBLP: +if (!sample_size) { +sample_size = sizeof(double); +sample = *(double*)pcm; +} +sample = fabs(sample); +vd->peak = FFMAX(vd->peak, sample); +vd->power += (sample*sample); +vd->nb_samples++; +} +av_assert0(sample_size != 0); +pcm += sample_size; +} } return ff_filter_frame(inlink->dst->outputs[0], samples); } #define MAX_DB 91 +#define VERY_SMALL 0.0001 static inline double logdb(uint64_t v) { @@ -88,9 +158,13 @@ static void print_stats(AVFilterContext *ctx) uint64_t nb_samples = 0, power = 0, nb_samples_shift = 0, sum = 0; uint64_t histdb[MAX_DB + 1] = { 0 }; +if (!vd->use_hist) +return; + for (i = 0; i < 0x1; i++) nb_sa
Re: [FFmpeg-devel] [PATCH] af_volumedetect: Work with sample formats other than s16/s16p
Thanks, I will use astats instead. On Sat, Aug 13, 2016 at 4:23 AM, Paul B Mahol wrote: > On 8/13/16, Nicolas George wrote: >> Le septidi 27 thermidor, an CCXXIV, Burt P a écrit : >>> The histogram will still only be shown for s16 and s16p. >>> >>> Signed-off-by: Burt P >>> --- >>> libavfilter/af_volumedetect.c | 133 >>> ++ >>> 1 file changed, 121 insertions(+), 12 deletions(-) >> >> Did you benchmark the original s16 case? The main point of this filter is >> that it is fast. With these changes, I see switches inside inner loops, and >> I am afraid it becomes less fast. > > Also, swresample already does what converting code do, but faster. > ___ > 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] af_volumedetect: Work with sample formats other than s16/s16p
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] [PATCHv5] af_hdcd: Extract generic HDCD decoder, wrap for ffmpeg
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
[FFmpeg-devel] [PATCH 0/3] libhdcd and things
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
[FFmpeg-devel] [PATCH 2/3] af_hdcd: check return value of av_frame_copy_props()
Anton Khirnov: "[av_frame_copy_props()] potentially contains memory allocation, so the return value needs to be checked." Signed-off-by: Burt P --- 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(&in); return AVERROR(ENOMEM); } -av_frame_copy_props(out, in); +result = av_frame_copy_props(out, in); +if (result) { +av_frame_free(&in); +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 3/3] af_hdcd: for easier maintenance alongside libhdcd
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 --- 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 @@ typedef struct
[FFmpeg-devel] [PATCH 1/3] fate: add test for af_hdcd analyze mode
Signed-off-by: Burt P --- 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
Re: [FFmpeg-devel] [PATCH 0/3] libhdcd and things
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