examples/rawout.c

Raw VBI output example.

00001 /*
00002  *  libzvbi raw VBI output example.
00003  *
00004  *  Copyright (C) 2006 Michael H. Schimek
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 /* $Id: rawout.c,v 1.5 2006/10/27 04:52:08 mschimek Exp $ */
00022 
00023 /* This example shows how to convert VBI data in a DVB PES stream
00024    to raw VBI data.
00025 
00026    gcc -o rawout rawout.c `pkg-config zvbi-0.2 --cflags --libs`
00027 
00028    ./rawout <pes | mplayer - -rawvideo on:w=720:h=34:format=0x32595559 */
00029 
00030 #undef NDEBUG
00031 #include <assert.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <unistd.h>
00036 
00037 #include <libzvbi.h>
00038 
00039 static vbi_dvb_demux *          dvb;
00040 static uint8_t                  pes_buffer[2048];
00041 static vbi_sampling_par         sp;
00042 static uint8_t *                image;
00043 static unsigned int             image_size;
00044 static unsigned int             pixel_mask;
00045 static int64_t                  last_pts;
00046 static vbi_raw_decoder          rd;
00047 
00048 static void
00049 raw_test                        (const vbi_sliced *     expect_sliced,
00050                                  unsigned int           expect_n_lines)
00051 {
00052         vbi_sliced sliced[50];
00053         unsigned int n_lines;
00054         unsigned int i;
00055 
00056         n_lines = vbi_raw_decode (&rd, image, sliced);
00057         assert (n_lines == expect_n_lines);
00058 
00059         for (i = 0; i < n_lines; ++i) {
00060                 unsigned int payload;
00061 
00062                 assert (sliced[i].id == expect_sliced[i].id);
00063                 assert (sliced[i].line == expect_sliced[i].line);
00064 
00065                 payload = (vbi_sliced_payload_bits (sliced[i].id) + 7) / 8;
00066                 assert (0 == memcmp (sliced[i].data,
00067                                      expect_sliced[i].data,
00068                                      payload));
00069         }
00070 }
00071 
00072 static vbi_bool
00073 convert                         (vbi_dvb_demux *        dx,
00074                                  void *                 user_data,
00075                                  const vbi_sliced *     sliced,
00076                                  unsigned int           n_lines,
00077                                  int64_t                pts)
00078 {
00079         vbi_bool success;
00080         ssize_t actual;
00081 
00082         dx = dx; /* unused */
00083         user_data = user_data;
00084 
00085         pts &= ((int64_t) 1 << 33) - 1;
00086 
00087         /* Handle PTS wrap-around. */
00088         if (0 == last_pts) {
00089                 last_pts = pts;
00090         } else if (pts < last_pts) {
00091                 last_pts -= (int64_t) 1 << 33;
00092         }
00093 
00094         while (pts - last_pts > 90000 / 25 * 3 / 2) {
00095                 /* No data for this frame. */
00096 
00097                 success = vbi_raw_video_image (image, image_size, &sp,
00098                                                0, 0, 0, pixel_mask, FALSE,
00099                                                NULL, /* n_lines */ 0);
00100                 assert (success);
00101 
00102                 raw_test (NULL, 0);
00103 
00104                 actual = write (STDOUT_FILENO, image, image_size);
00105                 assert (actual == (ssize_t) image_size);
00106 
00107                 last_pts += 90000 / 25;
00108         }
00109 
00110         success = vbi_raw_video_image (image, image_size, &sp,
00111                                        /* blank_level: default */ 0,
00112                                        /* black_level: default */ 0,
00113                                        /* white_level: default */ 0,
00114                                        pixel_mask,
00115                                        /* swap_fields */ FALSE,
00116                                        sliced, n_lines);
00117         assert (success);
00118 
00119         raw_test (sliced, n_lines);
00120 
00121         actual = write (STDOUT_FILENO, image, image_size);
00122         assert (actual == (ssize_t) image_size);
00123 
00124         last_pts = pts;
00125 
00126         return TRUE; /* success */
00127 }
00128 
00129 static void
00130 mainloop                        (void)
00131 {
00132         while (1 == fread (pes_buffer, sizeof (pes_buffer), 1, stdin)) {
00133                 vbi_bool success;
00134 
00135                 success = vbi_dvb_demux_feed (dvb,
00136                                               pes_buffer,
00137                                               sizeof (pes_buffer));
00138                 assert (success);
00139         }
00140 
00141         fprintf (stderr, "End of stream.\n");
00142 }
00143 
00144 int
00145 main                            (void)
00146 {
00147         if (isatty (STDIN_FILENO)) {
00148                 fprintf (stderr, "No DVB PES on standard input.\n");
00149                 exit (EXIT_FAILURE);
00150         }
00151 
00152         if (isatty (STDOUT_FILENO)) {
00153                 fprintf (stderr, "Output is binary image data. Pipe to "
00154                          "another tool or redirect to a file.\n");
00155                 exit (EXIT_FAILURE);
00156         }
00157 
00158         /* Helps debugging. */
00159         vbi_set_log_fn ((VBI_LOG_NOTICE |
00160                          VBI_LOG_WARNING |
00161                          VBI_LOG_ERROR),
00162                         vbi_log_on_stderr,
00163                         /* user_data */ NULL);
00164 
00165         dvb = vbi_dvb_pes_demux_new (convert, /* user_data */ NULL);
00166         assert (NULL != dvb);
00167 
00168         memset (&sp, 0, sizeof (sp));
00169 
00170 #if 1
00171         /* ITU BT.601 YUYV. */
00172 
00173         sp.scanning             = 625; /* PAL/SECAM */
00174         sp.sampling_format      = VBI_PIXFMT_YUYV;
00175         sp.sampling_rate        = 13.5e6;
00176         sp.bytes_per_line       = 720 * 2; /* 2 bpp */
00177         sp.offset               = 9.5e-6 * 13.5e6;
00178         sp.start[0]             = 6;
00179         sp.count[0]             = 17;
00180         sp.start[1]             = 319;
00181         sp.count[1]             = 17;
00182         sp.interlaced           = TRUE;
00183         sp.synchronous          = TRUE;
00184 
00185         /* Other bytes are left unmodified. */
00186         pixel_mask              = 0x000000FF; /* 0xAAVVUUYY */
00187 #else
00188         /* PAL square pixels BGRA32. */
00189 
00190         sp.scanning             = 625; /* PAL/SECAM */
00191         sp.sampling_format      = VBI_PIXFMT_BGRA32_LE;
00192         sp.sampling_rate        = 14.75e6;
00193         sp.bytes_per_line       = 768 * 4; /* 4 bpp */
00194         sp.offset               = 10.2e-6 * 14.75e6;
00195         sp.start[0]             = 6;
00196         sp.count[0]             = 17;
00197         sp.start[1]             = 319;
00198         sp.count[1]             = 17;
00199         sp.interlaced           = TRUE;
00200         sp.synchronous          = TRUE;
00201 
00202         pixel_mask              = 0x0000FF00; /* 0xAABBGGRR */
00203 #endif
00204 
00205         image_size = (sp.count[0] + sp.count[1]) * sp.bytes_per_line;
00206         image = malloc (image_size);
00207         assert (NULL != image);
00208 
00209         if (VBI_PIXFMT_YUYV == sp.sampling_format) {
00210                 /* Reset Cb/Cr bytes. */
00211                 memset (image, 0x80, image_size);
00212         } else {
00213                 memset (image, 0x00, image_size);
00214         }
00215 
00216         /* To verify the generated raw VBI data we feed it back
00217            into a decoder and compare the sliced VBI data. */
00218 
00219         vbi_raw_decoder_init (&rd);
00220 
00221         rd.scanning             = sp.scanning;
00222         rd.sampling_format      = sp.sampling_format;
00223         rd.sampling_rate        = sp.sampling_rate;
00224         rd.bytes_per_line       = sp.bytes_per_line;
00225         rd.offset               = sp.offset;
00226         rd.start[0]             = sp.start[0];
00227         rd.start[1]             = sp.start[1];
00228         rd.count[0]             = sp.count[0];
00229         rd.count[1]             = sp.count[1];
00230         rd.interlaced           = sp.interlaced;
00231         rd.synchronous          = sp.synchronous;
00232 
00233         /* Strict 0 because the function would consider the
00234            square pixel timing too tight to reliably decode
00235            Teletext. */
00236         vbi_raw_decoder_add_services (&rd,
00237                                       (VBI_SLICED_TELETEXT_B |
00238                                        VBI_SLICED_VPS |
00239                                        VBI_SLICED_CAPTION_625),
00240                                       /* strict */ 0);
00241 
00242         mainloop ();
00243 
00244         vbi_dvb_demux_delete (dvb);
00245 
00246         exit (EXIT_SUCCESS);
00247 
00248         return 0;
00249 }

Generated on Mon Dec 11 16:55:05 2006 for ZVBI Library by  doxygen 1.5.1