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

Marton Balint cus at passwd.hu
Tue Jan 12 23:40:27 CET 2016


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 <cus at passwd.hu>
---
 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 0000000..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 = calc_frequency(src, &offset)) < 0)
+        return -1;
+#ifdef TEST
+    printf("Frequency: %d, Offset: %d\n", frequency, offset);
+#endif
+
+    if (((offset + frequency * 359) >> 16) >= 720)
+        return -1;
+
+    for (i = 0; i < 360; i++, offset += frequency) {
+       int y_offset = offset >> 16;
+       int y_offset2 = (y_offset >= 719 ? y_offset : y_offset + 1);
+       int offset_frac = offset % 65536;
+       int value;
+       if (i % 8 == 0)
+           *++tgt = 0;
+       else
+           *tgt <<= 1;
+       value = src[y_offset << 1] * (65536 - offset_frac) + offset_frac * src[y_offset2 << 1];
+       if (value > DATA_ZERO_MAX << 16)
+           *tgt |= 1;
+#ifdef TEST
+       value = value - (DATA_ZERO_MAX << 16);
+       mindiff = FFMIN(mindiff, value > 0 ? value : -value);
+#endif
+    }
+
+    if (tgt0[1] != CLOCK_RUNIN || tgt0[2] != CLOCK_RUNIN || tgt0[3] != FRAMING_CODE)
+        return -1;
+
+#ifdef TEST
+    printf("Minimum difference from data_zero_max: %d\n", mindiff >> 16);
+#endif
+
+    tgt0[0] = 0x02; // data_unit_id
+    tgt0[1] = 0x2c; // data_unit_length
+    tgt0[2] = calc_parity_and_line_offset(line); // field_parity, line_offset
+
+    return 0;
+}
+
+#ifdef TEST
+
+const uint8_t samples[][720] = {
+    /* Sanity check */
+    {0},
+    /* Only use the binary levels and the whole line */
+    {162,162,16,16,162,162,16,16,162,162,16,16,162,162,16,16,162,162,16,16,162,162,16,16,162,162,16,16,162,162,16,16,162,162,162,162,162,162,16,16,16,16,162,162,16,16,16,16,162,162,162,162,16,16,16,16,162,162,162,162,162,162,16,16,162,162,162,162,16,16,16,16,162,162,162,162,162,162,16,16,162,162,162,162,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,162,162,162,162,16,16,16,16,16,16,16,16,162,162,162,162,162,162,16,16,162,162,16,16,16,16,162,162,16,16,162,162,162,162,162,162,16,16,16,16,162,162,16,16,162,162,162,162,162,162,162,162,16,16,16,16,16,16,16,16,16,16,162,162,162,162,162,162,162,162,162,162,16,16,16,16,162,162,162,162,162,162,16,16,16,16,16,16,162,162,16,16,162,162,162,162,162,162,162,162,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16,16,16,16,16,16,16,16,16,16,16,162,162,16,16,16,16},
+    /* The rest are taken from real-world teletext generators */
+    {16,16,16,16,16,15,20,112,160,61,21,124,155,50,27,135,148,39,35,144,140,31,44,152,129,24,55,158,118,19,67,162,105,16,80,163,92,16,93,165,164,164,166,158,67,15,15,26,127,153,50,15,15,37,138,167,167,133,33,15,15,56,153,167,164,164,166,106,17,77,162,166,164,89,15,15,18,103,166,164,164,167,154,55,24,126,167,164,164,167,140,39,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,96,163,80,15,16,16,16,16,16,16,16,16,16,16,15,37,138,167,164,164,167,129,29,15,16,16,16,16,15,73,160,166,164,164,164,87,16,99,163,76,15,15,22,118,158,55,24,126,167,164,164,167,140,39,15,15,48,152,129,24,55,154,167,164,164,164,164,165,96,17,15,16,16,16,16,16,15,21,112,167,164,164,164,164,164,164,167,142,41,15,15,46,146,167,164,164,167,118,23,15,16,16,15,80,163,96,16,90,164,164,164,164,164,166,157,64,15,16,16,16,16,16,16,15,39,144,140,35,15,16,16,16,16,16,16,16,16,16,16,15,83,163,92,15,16,16,16,16,16,16,16,16,16,16,15,29,132,150,46,15,16,16,16,16,16,16,16,16,16,16,15,67,161,109,19,15,16,16,16,16,16,16,16,16,16,15,22,118,158,59,15,16,16,16,16,16,16,16,16,16,16,15,53,155,124,25,15,16,16,16,16,16,16,16,16,16,15,17,102,162,73,15,16,16,16,16,16,16,16,16,16,16,15,41,146,137,33,15,16,16,16,16,16,16,16,16,16,16,15,86,163,89,15,16,16,16,16,16,16,16,16,16,16,15,31,135,148,43,15,16,16,16,16,16,16,16,16,16,16,15,70,162,105,18,15,16,16,16,16,16,16,16,16,16,15,23,121,156,56,15,16,16,16,16,16,16,16,16,16,16,15,56,156,121,23,15,16,16,16,16,16,16,16,16,16,15,18,105,162,70,15,16,16,16,16,16,16,16,16,16,16,15,43,148,135,31,15,16,16,16,16,16,16,16,16,16,16,15,89,163,86,15,16,16,16,16,16,16,16,16,16,16,15,33,137,146,41,15,16,16,16,16,16,16,16,16,16,16,15,73,162,102,17,15,16,16,16,16,16,16,16,16,16,15,25,124,155,53,15,16,16,16,16,16,16,16,16,16,16,15,59,158,118,22,15,16,16,16,16,16,16,16,16,16,15,19,109,161,67,15,16,16,16,16,16,16,16,16,16,16,15,46,150,132,29,15,16,16,16,16,16,16,16,16,16,16,15,92,163,83,15,16,16,16,16,16,16,16,16,16,16,15,35,140,144,39,15,16,16,16,16,16,16,16,16,16,16,15,76,163,99,17,15,16,16,16,16,16,16,16,16,16,15,26,127,153,50,15,16,16,16,16,16,16,16,16,16,16,15,61,159,115,21,15,16,16,16,16,16,16,16,16,16,15,20,112,160,64,15,16,16,16,16,16,16,16,16,16,16,15,48,152,129,28,15,16,16,16,16,16,16,16,16,16,16,16,96,163,80,15,16,16,16,16,16,16,16,16,16,16,15,37,142,142,37,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16},
+    {16,16,16,16,16,15,20,112,160,61,21,124,155,50,27,135,148,39,35,144,140,31,44,152,129,24,55,158,118,19,67,162,105,16,80,163,92,16,93,165,164,164,166,158,67,15,15,26,127,153,50,15,16,16,15,41,146,137,33,15,16,16,16,16,16,16,16,16,15,80,163,96,16,92,163,80,16,105,162,70,15,16,16,16,16,15,31,135,148,39,35,144,140,31,44,148,167,164,164,167,115,19,67,162,105,16,80,163,92,16,93,165,164,164,164,164,164,164,167,153,52,26,129,167,167,142,41,15,15,46,146,167,167,123,23,58,159,115,18,70,162,102,17,15,16,15,17,99,163,74,17,112,160,61,21,124,155,53,15,16,16,15,39,144,140,31,44,152,129,24,55,158,118,22,15,16,16,15,83,163,92,16,96,163,77,17,109,161,67,15,16,16,15,29,129,167,167,142,41,15,15,46,146,167,164,164,167,118,20,64,158,166,164,164,165,93,16,90,164,166,161,76,15,16,16,15,25,124,155,53,15,15,35,136,167,167,136,35,15,15,53,155,124,21,61,160,112,17,74,161,166,164,90,16,96,163,77,17,109,161,67,15,16,16,16,16,16,16,16,16,16,16,16,16,15,50,153,127,23,58,159,115,18,70,162,102,17,15,15,90,164,166,161,74,17,112,160,61,21,120,167,167,148,44,31,140,144,39,15,15,48,148,167,167,120,25,15,15,70,159,166,164,164,164,90,15,16,16,16,16,16,16,16,16,16,16,15,29,132,150,42,33,142,142,33,42,150,132,26,52,156,121,20,64,161,109,19,15,15,86,163,164,164,166,161,76,15,16,16,15,25,120,167,164,164,164,164,164,164,167,136,35,15,15,53,155,124,21,61,157,166,164,164,164,164,164,90,15,16,16,16,16,16,16,15,23,121,156,56,15,16,16,16,16,16,16,16,16,16,16,15,56,156,121,23,15,16,16,16,16,16,16,16,16,16,15,18,105,162,70,15,16,16,16,16,16,16,16,16,16,16,15,43,148,135,31,15,16,16,15,64,160,112,17,74,163,99,17,15,16,96,163,77,17,109,161,67,15,16,16,16,16,15,33,133,167,167,138,37,15,15,50,150,167,164,164,167,112,18,70,160,166,165,93,16,15,17,96,165,164,164,166,157,61,21,124,155,50,27,131,167,167,140,39,15,16,16,15,53,151,167,167,115,22,15,16,16,16,16,16,16,16,15,17,99,166,166,158,64,20,121,156,52,26,129,167,164,164,167,138,33,42,150,132,26,52,153,167,164,164,166,106,19,15,16,16,16,16,16,15,18,105,162,67,19,118,158,59,15,15,31,131,167,167,140,39,15,15,48,152,129,28,15,16,16,15,70,159,166,165,96,17,15,16,15,17,102,162,70,18,112,167,164,164,167,150,47,29,133,167,164,164,167,133,33,15,15,56,153,167,167,112,18,70,160,166,164,164,164,89,15,15,18,103,166,166,157,61,21,124,155,50,27,135,148,39,35,140,167,164,164,167,126,24,55,154,167,167,109,17,74,163,99,16,87,164,166,162,77,17,106,166,164,164,164,164,167,150,47,29,133,167,167,138,37,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16},
+    {16,16,16,16,7,20,109,159,61,22,116,155,61,28,128,148,48,37,139,139,37,37,148,128,28,48,155,116,22,61,155,102,17,74,159,88,16,80,161,169,161,170,156,77,10,1,27,121,155,58,8,13,16,16,16,16,16,16,13,8,58,149,116,22,56,149,175,164,93,17,74,161,88,16,88,161,74,17,93,164,165,161,171,150,66,7,3,36,132,141,47,5,5,45,141,174,169,121,27,6,16,16,16,10,13,77,156,169,161,169,161,88,13,1,20,99,166,165,161,171,150,55,8,13,15,7,45,132,170,162,161,161,161,161,165,166,111,27,6,16,10,13,77,161,169,161,161,161,161,161,170,156,66,10,11,16,6,35,121,168,164,161,161,161,161,162,168,121,35,6,16,11,10,66,150,170,161,161,161,161,161,169,161,88,13,10,16,7,27,111,166,165,161,161,161,161,161,170,132,45,7,14,13,8,55,141,171,161,161,161,165,164,93,17,74,161,88,16,88,161,74,17,93,164,175,149,56,22,116,148,48,27,118,170,162,162,170,132,35,3,7,55,150,175,167,106,21,68,156,170,161,169,161,88,16,1,20,99,164,176,149,56,21,106,166,164,161,171,141,45,5,5,45,132,174,169,118,27,56,149,171,161,165,164,99,20,1,16,88,161,177,161,68,17,93,164,165,161,171,150,66,7,3,35,121,172,172,130,35,35,140,171,161,164,166,111,27,1,10,77,156,176,164,80,16,80,161,169,161,170,156,77,10,1,27,111,167,174,140,45,27,130,170,162,162,170,121,35,3,7,66,150,175,167,106,17,68,156,170,161,169,161,88,16,1,20,99,164,175,149,56,21,106,168,164,161,171,132,45,5,5,45,141,174,169,118,21,56,149,171,161,167,164,99,20,1,16,88,161,177,156,68,17,93,166,165,161,171,150,55,7,3,35,132,172,172,130,35,45,140,171,161,165,166,111,27,1,13,77,156,176,161,80,16,80,161,167,161,170,156,66,10,1,27,111,169,174,140,45,35,130,170,162,162,168,121,35,3,10,66,150,175,167,93,17,68,156,169,161,169,161,88,13,1,20,99,167,175,149,56,21,118,168,164,161,170,130,35,35,130,171,161,164,168,106,21,56,149,171,161,167,164,93,16,80,161,169,161,170,156,68,17,106,166,165,161,171,140,45,27,118,170,162,162,170,130,27,45,140,171,161,165,166,106,21,68,156,170,161,169,161,80,16,80,164,167,161,170,149,56,21,106,166,164,161,171,140,35,35,130,170,162,164,168,118,27,56,149,171,161,165,164,93,17,68,161,169,161,169,161,68,17,93,164,165,161,171,149,56,27,118,168,164,162,170,130,35,35,140,171,161,164,166,106,21,56,149,170,161,167,164,80,16,80,161,169,161,170,156,68,21,106,166,165,161,171,140,45,27,130,170,162,162,170,118,27,45,140,171,161,165,166,106,17,68,156,170,161,169,161,80,16,93,164,167,161,171,149,56,21,106,168,164,161,171,130,35,35,130,170,161,164,168,118,21,56,149,175,167,93,17,74,159,96,16,1,16,96,159,84,13,1,27,111,166,165,161,161,161,171,141,45,5,5,47,141,132,36,6,15,16,16,16,16,16,16,16,16,16,16},
+    {16,16,16,16,7,20,109,159,61,22,116,155,61,28,128,148,48,37,139,139,37,37,148,128,28,48,155,116,22,61,155,102,17,74,159,88,16,80,161,169,161,170,156,77,10,1,27,121,155,58,7,3,35,132,170,162,161,161,164,168,118,27,61,155,121,27,6,16,10,13,84,161,96,16,8,16,16,16,16,16,16,16,6,27,111,168,164,161,171,130,35,37,139,141,36,3,7,58,155,121,27,6,16,16,16,16,16,8,16,96,161,96,13,1,20,99,167,175,150,66,10,13,15,6,36,141,141,47,7,14,16,16,16,16,11,10,71,155,116,17,68,156,176,161,80,16,80,161,176,156,77,13,11,16,6,27,121,149,58,8,13,16,16,14,7,47,149,132,36,3,10,71,155,116,22,68,156,170,161,169,161,80,16,88,159,74,17,93,167,175,149,56,22,128,148,48,28,139,139,37,35,130,174,169,118,27,56,149,171,161,161,161,167,164,99,16,8,16,16,16,16,16,7,20,111,167,175,150,66,8,13,16,16,14,7,47,141,139,28,45,140,171,161,161,161,165,166,93,17,68,156,169,161,161,161,169,156,68,17,93,167,175,149,56,21,118,169,174,140,35,37,139,139,37,48,148,132,36,1,10,66,150,171,161,167,164,99,16,1,16,96,161,84,13,1,20,111,167,175,149,56,28,128,149,58,5,5,45,132,170,161,161,161,164,166,111,27,6,16,16,16,16,16,16,16,8,16,96,159,84,13,10,16,16,16,16,16,16,16,16,15,7,47,141,141,47,6,15,16,16,16,16,16,16,16,16,10,13,84,161,96,16,8,16,16,16,16,16,16,16,16,16,6,36,132,149,58,7,14,16,16,16,16,16,16,16,16,11,10,71,155,109,20,7,16,16,16,8,16,96,159,84,13,10,16,16,16,16,16,6,36,132,148,37,35,130,170,162,164,168,121,35,1,10,71,155,116,17,68,156,176,161,88,16,8,16,16,16,7,20,111,167,175,150,66,8,13,16,16,14,7,45,132,172,169,118,27,48,155,116,22,61,155,102,17,68,156,169,161,169,161,88,13,1,20,99,167,175,150,66,10,3,35,121,168,162,162,170,132,45,6,15,16,16,16,16,11,10,71,159,109,20,7,16,16,16,8,16,109,159,84,13,11,16,6,27,111,168,164,161,171,132,45,5,5,47,149,128,28,45,149,171,161,161,161,161,161,167,164,88,16,8,16,8,20,99,164,167,161,171,150,66,10,13,15,6,36,141,139,37,35,130,174,169,121,35,6,16,16,16,16,16,16,16,10,16,96,161,96,16,1,20,99,164,175,150,66,10,1,35,121,168,164,162,170,132,45,7,15,13,8,58,155,116,22,56,149,170,161,161,161,161,161,169,161,80,17,102,159,84,10,1,27,111,166,164,161,171,141,45,7,14,14,7,58,149,128,28,56,149,175,167,111,20,7,16,10,16,96,161,88,16,93,164,167,161,161}
+};
+
+int main(void) {
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(samples); i++) {
+        int ret, j;
+        uint8_t buf[46];
+        uint8_t src[1440];
+
+        for (j = 0; j < 720; j++)
+            src[j*2+1] = samples[i][j];
+
+        printf("Sample %d\n", i);
+        ret = ff_teletext_line_from_vbi_data(7, src, buf);
+        if (ret >= 0) {
+            int k;
+            printf("Teletext:");
+            for (k = 0; k < 46; k++)
+                printf(" %02x", buf[k]);
+            printf("\n");
+        } else
+            printf("Teletext decoding failed.\n");
+    }
+    return 0;
+}
+
+#endif
+
diff --git a/libavdevice/teletext_quantizer.h b/libavdevice/teletext_quantizer.h
new file mode 100644
index 0000000..7bfa0d9
--- /dev/null
+++ b/libavdevice/teletext_quantizer.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+#ifndef AVDEVICE_TELETEXT_QUANTIZER_H
+#define AVDEVICE_TELETEXT_QUANTIZER_H
+
+/**
+ * Decode a VBI line to a DVB teletext data unit.
+ *
+ * @param line  VBI line number
+ * @param src   a 720 pixel wide VBI line in AV_PIX_FMT_UYVY422 format
+ * @param tgt   a 46 byte long buffer for the DVB teletext data unit
+ * @return  negative on error or if no teletext data could be decoded
+ */
+int ff_teletext_line_from_vbi_data(int line, const uint8_t *src, uint8_t *tgt);
+
+#endif /* AVDEVICE_TELETEXT_QUANTIZER_H */
diff --git a/tests/fate/libavdevice.mak b/tests/fate/libavdevice.mak
index cb6af51..d177dd9 100644
--- a/tests/fate/libavdevice.mak
+++ b/tests/fate/libavdevice.mak
@@ -1,6 +1,9 @@
-FATE_LIBAVDEVICE-yes += fate-timefilter
+FATE_LIBAVDEVICE-yes += fate-timefilter fate-teletext_quantizer
 fate-timefilter: libavdevice/timefilter-test$(EXESUF)
 fate-timefilter: CMD = run libavdevice/timefilter-test
 
+fate-teletext_quantizer: libavdevice/teletext_quantizer-test$(EXESUF)
+fate-teletext_quantizer: CMD = run libavdevice/teletext_quantizer-test
+
 FATE-$(CONFIG_AVDEVICE) += $(FATE_LIBAVDEVICE-yes)
 fate-libavdevice: $(FATE_LIBAVDEVICE-yes)
diff --git a/tests/ref/fate/teletext_quantizer b/tests/ref/fate/teletext_quantizer
new file mode 100644
index 0000000..ae9187f
--- /dev/null
+++ b/tests/ref/fate/teletext_quantizer
@@ -0,0 +1,22 @@
+Sample 0
+Teletext decoding failed.
+Sample 1
+Frequency: 131072, Offset: 32768
+Minimum difference from data_zero_max: 73
+Teletext: 02 2c 27 e4 ce ce e0 04 07 0e 97 2f 07 ce 2f 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04
+Sample 2
+Frequency: 127557, Offset: 506146
+Minimum difference from data_zero_max: 51
+Teletext: 02 2c 27 e4 ce ce e0 04 07 0e 97 2f 07 ce 2f 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04
+Sample 3
+Frequency: 127557, Offset: 506146
+Minimum difference from data_zero_max: 51
+Teletext: 02 2c 27 e4 40 a8 57 57 d9 a8 a8 a8 a8 ce ec 4c ad 40 2a 6b 4c e0 2a a7 1f 2f 04 04 04 04 52 86 76 75 8c 0d 75 c1 4c 8c 5d cd cd 5d ad ec
+Sample 4
+Frequency: 127590, Offset: 442283
+Minimum difference from data_zero_max: 45
+Teletext: 02 2c 27 e4 0b 57 26 1c e3 e3 e3 e3 e3 e3 d5 ae 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e ee ee ee ee ee ee ee ee ee ee ee ee d2 79
+Sample 5
+Frequency: 127590, Offset: 442283
+Minimum difference from data_zero_max: 46
+Teletext: 02 2c 27 e4 f4 40 e9 04 c4 16 c4 25 d6 ad e0 c2 f7 b6 a7 26 9e 04 04 04 04 04 20 b9 61 86 ae 67 04 23 97 c7 16 04 ce 2f a7 16 2c 00 00 00
-- 
2.6.2



More information about the ffmpeg-devel mailing list