Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-14 Thread Carl Eugen Hoyos
Andrey Turkin  gmail.com> writes:

> Slicer is a part of the library and as such is under 
> LGPL; in fact FFmpeg already uses the library to 
> decode DVB teletext.

But FFmpeg's configure claims libzvbi is GPL, 
an LGPL replacement for at least some functionality 
is certainly welcome!

Carl Eugen

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


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-14 Thread Marton Balint


On Wed, 13 Jan 2016, Michael Niedermayer wrote:


On Wed, Jan 13, 2016 at 05:01:01AM +0300, Andrey Turkin wrote:

Why not use libzvbi's slicer? It should be pretty robust with
less-than-ideal signal.

Regarding your code - is there a need to calculate a frequency? I did
something similar a while back with VBI from TV signal and in my experience:

a) this kind of frequency/phase estimation doesn't work that well on a
noisy signal.



 b) there's really no need to estimate frequency - it's a known constant
(well it depends on a standard but in each standard it is a constant) and
generators usually don't deviate from it; you just need to get a good phase
estimation based on, say, local maxima/minima of run-in bits.


to calculate the phase



[...]

Thank you all for the comments and suggestions, I have learned a lot from 
it. The reason why I did not use libzvbi was not licensing, I simply 
wasn't sure at first that this can be done conveniently with it, and 
instead of checking the docs, writing it from scratch was more fun.


Anyway, now I know that I can almost seamlessly replace the 
teletext_qunatizer stuff with libzvbi's vbi_bit_slicer, so I will rework 
the patch series to use that. The higher level interface of libzvbi - 
vbi_raw_decoder seems too high level (bloated) for my use case.


As for the licensing, I believe now that libzvbi is LGPL because it 
references the GNU Library General Public License wich is the predecessor 
of the LGPL, so I will submit a patch to remove the GPL depdendency from 
libzvbi as well.


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


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Kieran Kunhya
On Wed, 13 Jan 2016 at 02:16 Andrey Turkin  wrote:

> Why not use libzvbi's slicer? It should be pretty robust with
> less-than-ideal signal.
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Kieran Kunhya
On Wed, 13 Jan 2016 at 02:16 Andrey Turkin  wrote:

> Why not use libzvbi's slicer? It should be pretty robust with
> less-than-ideal signal.
>

(now with a proper response).
IMO FFmpeg shouldn't be doing analogue signal processing. This should be
left to libzvbi.

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


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Michael Niedermayer
On Wed, Jan 13, 2016 at 05:01:01AM +0300, Andrey Turkin wrote:
> Why not use libzvbi's slicer? It should be pretty robust with
> less-than-ideal signal.
> 
> Regarding your code - is there a need to calculate a frequency? I did
> something similar a while back with VBI from TV signal and in my experience:
> 
> a) this kind of frequency/phase estimation doesn't work that well on a
> noisy signal.

>  b) there's really no need to estimate frequency - it's a known constant
> (well it depends on a standard but in each standard it is a constant) and
> generators usually don't deviate from it; you just need to get a good phase
> estimation based on, say, local maxima/minima of run-in bits.

to calculate the phase

the area that has alternating 0/1 values can be correlated with a
sin() and a cos(), if you consider the 2 resulting values as x and y
coordinates the angle they form from the origin is the phase.
(this can be worded simpler using complex numbers)

when above is done its essential that a whole multiple of cycles is
used the important part is that the used sin(x) and cos(x) vectors are
orthogonal, that is sum sin(x) * cos(x) over the x values considered is
0 cutting them off randomls would break that
(its also possible to use windowing instead of a exact multiple of cycles)

consider that the phase is 0 so our signal input is exactly
cos(x) (if we define that as 0°), the dot product of that with cos(x)
is "1" and sin(x) is 0
now if our input is shifted by 90deg that is it matches sin(x)
then the dot product with a cos(x) vector is 0 and sin(x) is 1
...
(also i for simpliity normalized the values, sum of cos(x)*cos(x) for
x from 0 to n would of course be larger than 1 for a larger n)

PS: not complaining about calculating the phase by some other means
above is just a suggestion

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

While the State exists there can be no freedom; when there is freedom there
will be no State. -- Vladimir Lenin


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Carl Eugen Hoyos
Andrey Turkin  gmail.com> writes:

> Why not use libzvbi's slicer? It should be pretty 
> robust with less-than-ideal signal.

It is not entirely available under LGPL afaict.

Carl Eugen

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


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Michael Niedermayer
On Thu, Jan 14, 2016 at 01:41:51AM +0300, Andrey Turkin wrote:
> 2016-01-13 22:32 GMT+03:00 Michael Niedermayer :
> 
> > to calculate the phase
> >
> > the area that has alternating 0/1 values can be correlated with a
> > sin() and a cos(), if you consider the 2 resulting values as x and y
> > coordinates the angle they form from the origin is the phase.
> > (this can be worded simpler using complex numbers)
> >
> > when above is done its essential that a whole multiple of cycles is
> > used the important part is that the used sin(x) and cos(x) vectors are
> > orthogonal, that is sum sin(x) * cos(x) over the x values considered is
> > 0 cutting them off randomls would break that
> > (its also possible to use windowing instead of a exact multiple of cycles)
> >
> > consider that the phase is 0 so our signal input is exactly
> > cos(x) (if we define that as 0°), the dot product of that with cos(x)
> > is "1" and sin(x) is 0
> > now if our input is shifted by 90deg that is it matches sin(x)
> > then the dot product with a cos(x) vector is 0 and sin(x) is 1
> > ...
> > (also i for simpliity normalized the values, sum of cos(x)*cos(x) for
> > x from 0 to n would of course be larger than 1 for a larger n)
> >
> 
> That should work; I wonder about runtime cost though. sin/cos for a given
> frequency can be precomputated; atan2 can be turned to table or something.
> Still there'd be about 32 multiplications to get a phase (over 4 periods).
> That's more than 25000 multiplications per second per teletext standard.

25000 operations per second is not much, copying the images takes
orders of magnitude more

[...]
-- 
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


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Andrey Turkin
Slicer is a part of the library and as such is under LGPL; in fact FFmpeg
already uses the library to decode DVB teletext.



2016-01-14 1:27 GMT+03:00 Carl Eugen Hoyos :

> Andrey Turkin  gmail.com> writes:
>
> > Why not use libzvbi's slicer? It should be pretty
> > robust with less-than-ideal signal.
>
> It is not entirely available under LGPL afaict.
>
> Carl Eugen
>
> ___
> 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 2/3] lavd: add teletext quantizer

2016-01-13 Thread Andrey Turkin
2016-01-13 22:32 GMT+03:00 Michael Niedermayer :

> to calculate the phase
>
> the area that has alternating 0/1 values can be correlated with a
> sin() and a cos(), if you consider the 2 resulting values as x and y
> coordinates the angle they form from the origin is the phase.
> (this can be worded simpler using complex numbers)
>
> when above is done its essential that a whole multiple of cycles is
> used the important part is that the used sin(x) and cos(x) vectors are
> orthogonal, that is sum sin(x) * cos(x) over the x values considered is
> 0 cutting them off randomls would break that
> (its also possible to use windowing instead of a exact multiple of cycles)
>
> consider that the phase is 0 so our signal input is exactly
> cos(x) (if we define that as 0°), the dot product of that with cos(x)
> is "1" and sin(x) is 0
> now if our input is shifted by 90deg that is it matches sin(x)
> then the dot product with a cos(x) vector is 0 and sin(x) is 1
> ...
> (also i for simpliity normalized the values, sum of cos(x)*cos(x) for
> x from 0 to n would of course be larger than 1 for a larger n)
>

That should work; I wonder about runtime cost though. sin/cos for a given
frequency can be precomputated; atan2 can be turned to table or something.
Still there'd be about 32 multiplications to get a phase (over 4 periods).
That's more than 25000 multiplications per second per teletext standard.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-12 Thread Marton Balint
Getting teletext right from VANC/VBI data is tricky, because the teletext clock
is not synced to the video clock. Therefore we have to first measure the
frequency of the teletext clock in the reconstructed signal, and then resample
the original data appropriately.

What I do is that I measure the distance between the first and the last zero
crossing (leading edge) in the first 3 (constant) bytes of the input to
calculate the clock frequency and the starting point of the real teletext data.

Based on these I can calculate the offsets where the rest of the signal needs
to be quantized, and I do that by a simple linear interpolation between two
neighbouring values in the original data, so the resampling method is simple
first order hold.

Fixed point arithmethic is used for frequencies and offsets to improve
precision.

I guess the DSP minded people can come up with a better way, but it works for
me just fine as it is.

Signed-off-by: Marton Balint 
---
 libavdevice/Makefile  |   2 +-
 libavdevice/teletext_quantizer.c  | 174 ++
 libavdevice/teletext_quantizer.h  |  32 +++
 tests/fate/libavdevice.mak|   5 +-
 tests/ref/fate/teletext_quantizer |  22 +
 5 files changed, 233 insertions(+), 2 deletions(-)
 create mode 100644 libavdevice/teletext_quantizer.c
 create mode 100644 libavdevice/teletext_quantizer.h
 create mode 100644 tests/ref/fate/teletext_quantizer

diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index f57ec0b..f889b7c 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -69,4 +69,4 @@ SKIPHEADERS-$(CONFIG_V4L2_OUTDEV)+= v4l2-common.h
 SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa.h
 SKIPHEADERS-$(HAVE_SNDIO_H)  += sndio.h
 
-TESTPROGS = timefilter
+TESTPROGS = timefilter teletext_quantizer
diff --git a/libavdevice/teletext_quantizer.c b/libavdevice/teletext_quantizer.c
new file mode 100644
index 000..af6dbbf
--- /dev/null
+++ b/libavdevice/teletext_quantizer.c
@@ -0,0 +1,174 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/mem.h"
+#include "config.h"
+#include "teletext_quantizer.h"
+
+#define BLACK_LEVEL 16
+#define WHITE_LEVEL 235
+#define DATA_ZERO_LEVEL (BLACK_LEVEL)
+#define DATA_ONE_LEVEL (BLACK_LEVEL + ((WHITE_LEVEL - BLACK_LEVEL) * 2 / 3))
+#define DATA_ZERO_MAX ((DATA_ONE_LEVEL + DATA_ZERO_LEVEL) / 2)
+#define MAX_FRAMING_CODE_END_POSITION 64
+
+#define CLOCK_RUNIN  0xaa
+#define FRAMING_CODE 0xe4
+
+static inline int calc_zerocross(int i, uint8_t y1, uint8_t y2)
+{
+return 65536 * i + 65536 * (DATA_ZERO_MAX - y1) / (y2 - y1);
+}
+
+static int calc_frequency(const uint8_t *src, int *offset)
+{
+int first_cross = 0, last_cross = 0;
+int crosses = 0;
+uint8_t last = DATA_ZERO_LEVEL;
+int frequency;
+int i;
+
+/* Teletext data starts with 3 constant bytes: 10101010 10101010 11100100.
+ * Lets find the 10th leading edge zero crossing, (actually DATA_ZERO_MAX
+ * crossing) which should be at the 6th bit of the third byte. */
+for (i = 0; i < MAX_FRAMING_CODE_END_POSITION; src += 2, i++) {
+   uint8_t val = *src;
+   if (val > DATA_ZERO_MAX && last <= DATA_ZERO_MAX) {
+   crosses++;
+   if (crosses == 1 || crosses == 10) {
+   last_cross = calc_zerocross(i - 1, last, val);
+   if (crosses == 1)
+   first_cross = last_cross;
+   else
+   break;
+   }
+   }
+   last = val;
+}
+
+if (i >= MAX_FRAMING_CODE_END_POSITION)
+return -1;
+
+frequency = (last_cross - first_cross) / 21;
+*offset = FFMAX(0, first_cross + frequency / 2);
+
+return frequency;
+}
+
+static uint8_t calc_parity_and_line_offset(int line)
+{
+uint8_t ret = (line < 313) << 5;
+if (line >= 7 && line <= 22)
+ret += line;
+if (line >= 320 && line <= 335)
+ret += (line - 313);
+return ret;
+}
+
+int ff_teletext_line_from_vbi_data(int line, const uint8_t *src, uint8_t *tgt)
+{
+int i, offset, frequency;
+uint8_t *tgt0 = tgt;
+#ifdef TEST
+int mindiff = 255 << 16;
+#endif
+
+src++;
+
+if ((frequency = 

Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-12 Thread Andrey Turkin
Why not use libzvbi's slicer? It should be pretty robust with
less-than-ideal signal.

Regarding your code - is there a need to calculate a frequency? I did
something similar a while back with VBI from TV signal and in my experience:

a) this kind of frequency/phase estimation doesn't work that well on a
noisy signal.
 b) there's really no need to estimate frequency - it's a known constant
(well it depends on a standard but in each standard it is a constant) and
generators usually don't deviate from it; you just need to get a good phase
estimation based on, say, local maxima/minima of run-in bits.

Ideal frequency (or rather period) for WST in your code should be 127530; I
presume 4 last samples are WST so their estimated frequency is pretty far
outside specified 25ppm tolerance. Value of 127590 means  that for the last
bit you get a (127590-127530)/65536*360 phase error which is about 1/3 of
period (still within the sample if initial phase was estimated accurately -
but getting close to the edge). However any additional error in estimated
frequency would cause lost or duplicate bits in the last bits of decoded
data. If SDI data is noisy there's a good chance of that happening (and
noisy SDI is not some theoretical possibility - one of local TV studios has
a rather strange setup where they do several SDI->analog and analog->SDI
conversions; frames coming from their last SDI output are already noisy).

2016-01-13 1:40 GMT+03:00 Marton Balint :

> Getting teletext right from VANC/VBI data is tricky, because the teletext
> clock
> is not synced to the video clock. Therefore we have to first measure the
> frequency of the teletext clock in the reconstructed signal, and then
> resample
> the original data appropriately.
>
> What I do is that I measure the distance between the first and the last
> zero
> crossing (leading edge) in the first 3 (constant) bytes of the input to
> calculate the clock frequency and the starting point of the real teletext
> data.
>
> Based on these I can calculate the offsets where the rest of the signal
> needs
> to be quantized, and I do that by a simple linear interpolation between two
> neighbouring values in the original data, so the resampling method is
> simple
> first order hold.
>
> Fixed point arithmethic is used for frequencies and offsets to improve
> precision.
>
> I guess the DSP minded people can come up with a better way, but it works
> for
> me just fine as it is.
>
> Signed-off-by: Marton Balint 
> ---
>  libavdevice/Makefile  |   2 +-
>  libavdevice/teletext_quantizer.c  | 174
> ++
>  libavdevice/teletext_quantizer.h  |  32 +++
>  tests/fate/libavdevice.mak|   5 +-
>  tests/ref/fate/teletext_quantizer |  22 +
>  5 files changed, 233 insertions(+), 2 deletions(-)
>  create mode 100644 libavdevice/teletext_quantizer.c
>  create mode 100644 libavdevice/teletext_quantizer.h
>  create mode 100644 tests/ref/fate/teletext_quantizer
>
> diff --git a/libavdevice/Makefile b/libavdevice/Makefile
> index f57ec0b..f889b7c 100644
> --- a/libavdevice/Makefile
> +++ b/libavdevice/Makefile
> @@ -69,4 +69,4 @@ SKIPHEADERS-$(CONFIG_V4L2_OUTDEV)+= v4l2-common.h
>  SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa.h
>  SKIPHEADERS-$(HAVE_SNDIO_H)  += sndio.h
>
> -TESTPROGS = timefilter
> +TESTPROGS = timefilter teletext_quantizer
> diff --git a/libavdevice/teletext_quantizer.c
> b/libavdevice/teletext_quantizer.c
> new file mode 100644
> index 000..af6dbbf
> --- /dev/null
> +++ b/libavdevice/teletext_quantizer.c
> @@ -0,0 +1,174 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#include "libavutil/common.h"
> +#include "libavutil/mem.h"
> +#include "config.h"
> +#include "teletext_quantizer.h"
> +
> +#define BLACK_LEVEL 16
> +#define WHITE_LEVEL 235
> +#define DATA_ZERO_LEVEL (BLACK_LEVEL)
> +#define DATA_ONE_LEVEL (BLACK_LEVEL + ((WHITE_LEVEL - BLACK_LEVEL) * 2 /
> 3))
> +#define DATA_ZERO_MAX ((DATA_ONE_LEVEL + DATA_ZERO_LEVEL) / 2)
> +#define MAX_FRAMING_CODE_END_POSITION 64
> +
> +#define CLOCK_RUNIN  0xaa
> +#define FRAMING_CODE 0xe4
> +
> +static inline int calc_zerocross(int i, uint8_t y1, uint8_t y2)