Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer
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
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
On Wed, 13 Jan 2016 at 02:16 Andrey Turkinwrote: > 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
On Wed, 13 Jan 2016 at 02:16 Andrey Turkinwrote: > 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
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
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
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
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 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
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
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)